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.

2255 lines
86 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. #include "fe.h"
  12. //=====================================================================
  13. // CStateSets interface
  14. //
  15. //---------------------------------------------------------------------
  16. #undef DPF_MODNAME
  17. #define DPF_MODNAME "CStateSets::CStateSets"
  18. CStateSets::CStateSets(): m_SetHandles(10), m_DeviceHandles(10), m_GrowSize(10)
  19. {
  20. m_dwMaxSets = 0;
  21. m_dwCurrentHandle = __INVALIDHANDLE;
  22. m_pStateSets = NULL;
  23. // Init handle factory
  24. // m_SetHandles.Init(m_GrowSize, m_GrowSize);
  25. m_SetHandles.CreateNewHandle( NULL ); // Reserve handle 0
  26. // m_DeviceHandles.Init(m_GrowSize, m_GrowSize);
  27. m_DeviceHandles.CreateNewHandle( NULL ); // Reserve handle 0
  28. }
  29. //---------------------------------------------------------------------
  30. #undef DPF_MODNAME
  31. #define DPF_MODNAME "CStateSets::~CStateSets"
  32. CStateSets::~CStateSets()
  33. {
  34. delete m_pBufferSet;
  35. delete [] m_pStateSets;
  36. m_SetHandles.ReleaseHandle(0);
  37. m_DeviceHandles.ReleaseHandle(0);
  38. }
  39. //---------------------------------------------------------------------
  40. #undef DPF_MODNAME
  41. #define DPF_MODNAME "CStateSets::Init"
  42. HRESULT CStateSets::Init(CD3DBase *pDev)
  43. {
  44. m_bPure = (pDev->BehaviorFlags() & D3DCREATE_PUREDEVICE) != 0;
  45. m_bTLHal = (pDev->GetDDIType() == D3DDDITYPE_DX7TL) || (pDev->GetDDIType() == D3DDDITYPE_DX8TL);
  46. m_bDX8Dev = (pDev->GetDDIType() >= D3DDDITYPE_DX8);
  47. m_bHardwareVP = (pDev->BehaviorFlags() &
  48. D3DCREATE_HARDWARE_VERTEXPROCESSING);
  49. if(pDev->GetDDIType() > D3DDDITYPE_DX7TL)
  50. {
  51. DWORD value = 0;
  52. GetD3DRegValue(REG_DWORD, "EmulateStateBlocks", &value, sizeof(DWORD));
  53. if(value == 0)
  54. {
  55. m_bEmulate = FALSE;
  56. }
  57. else
  58. {
  59. m_bEmulate = TRUE;
  60. }
  61. }
  62. else
  63. {
  64. m_bEmulate = TRUE;
  65. }
  66. if(m_bPure)
  67. {
  68. m_pBufferSet = new CPureStateSet;
  69. }
  70. else
  71. {
  72. m_pBufferSet = new CStateSet;
  73. }
  74. return D3D_OK;
  75. }
  76. //---------------------------------------------------------------------
  77. #undef DPF_MODNAME
  78. #define DPF_MODNAME "CStateSets::StartNewSet"
  79. HRESULT CStateSets::StartNewSet()
  80. {
  81. m_dwCurrentHandle = m_SetHandles.CreateNewHandle( NULL );
  82. if (m_dwCurrentHandle == __INVALIDHANDLE)
  83. return E_OUTOFMEMORY;
  84. if (m_dwCurrentHandle >= m_dwMaxSets)
  85. {
  86. // Time to grow the array
  87. CStateSet *pNew;
  88. if(m_bPure)
  89. {
  90. pNew = new CPureStateSet[m_dwMaxSets + m_GrowSize];
  91. }
  92. else
  93. {
  94. pNew = new CStateSet[m_dwMaxSets + m_GrowSize];
  95. }
  96. if (pNew == NULL)
  97. {
  98. m_SetHandles.ReleaseHandle(m_dwCurrentHandle);
  99. return E_OUTOFMEMORY;
  100. }
  101. for (DWORD i=0; i < m_dwMaxSets; i++)
  102. pNew[i] = m_pStateSets[i];
  103. delete [] m_pStateSets;
  104. m_pStateSets = pNew;
  105. m_dwMaxSets += m_GrowSize;
  106. }
  107. m_pBufferSet->m_FEOnlyBuffer.Reset();
  108. m_pBufferSet->m_DriverBuffer.Reset();
  109. m_pCurrentStateSet = m_pBufferSet;
  110. return D3D_OK;
  111. }
  112. //---------------------------------------------------------------------
  113. #undef DPF_MODNAME
  114. #define DPF_MODNAME "CStateSets::EndSet"
  115. void CStateSets::EndSet()
  116. {
  117. m_pStateSets[m_dwCurrentHandle] = *m_pCurrentStateSet;
  118. m_pCurrentStateSet = &m_pStateSets[m_dwCurrentHandle];
  119. m_pCurrentStateSet->m_dwStateSetFlags |= __STATESET_INITIALIZED;
  120. }
  121. //---------------------------------------------------------------------
  122. #undef DPF_MODNAME
  123. #define DPF_MODNAME "CStateSets::DeleteStateSet"
  124. void CStateSets::DeleteStateSet(CD3DBase *pDevI, DWORD dwHandle)
  125. {
  126. if (dwHandle >= m_dwMaxSets)
  127. {
  128. D3D_ERR("State block handle is greater than available number of blocks");
  129. throw D3DERR_INVALIDCALL;
  130. }
  131. CStateSet *pStateSet = &m_pStateSets[dwHandle];
  132. if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
  133. {
  134. D3D_ERR("State block is not initialized");
  135. throw D3DERR_INVALIDCALL;
  136. }
  137. // Pass delete instruction to the driver only if there was some data recorded
  138. if (pStateSet->m_dwDeviceHandle != __INVALIDHANDLE)
  139. pDevI->m_pDDI->InsertStateSetOp(D3DHAL_STATESETDELETE,
  140. pStateSet->m_dwDeviceHandle,
  141. (D3DSTATEBLOCKTYPE)0);
  142. Cleanup(dwHandle);
  143. }
  144. //---------------------------------------------------------------------
  145. #undef DPF_MODNAME
  146. #define DPF_MODNAME "CStateSets::Cleanup"
  147. void CStateSets::Cleanup(DWORD dwHandle)
  148. {
  149. CStateSet &pStateSet = m_pStateSets[dwHandle];
  150. m_SetHandles.ReleaseHandle(dwHandle);
  151. if (pStateSet.m_dwDeviceHandle != __INVALIDHANDLE)
  152. m_DeviceHandles.ReleaseHandle(pStateSet.m_dwDeviceHandle);
  153. pStateSet.Release();
  154. }
  155. //---------------------------------------------------------------------
  156. #undef DPF_MODNAME
  157. #define DPF_MODNAME "CStateSets::Capture"
  158. void CStateSets::Capture(CD3DBase *pDevI, DWORD dwHandle)
  159. {
  160. if (dwHandle >= m_dwMaxSets)
  161. {
  162. D3D_ERR("Invalid state block handle");
  163. throw D3DERR_INVALIDCALL;
  164. }
  165. CStateSet *pStateSet = &m_pStateSets[dwHandle];
  166. if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
  167. {
  168. D3D_ERR("State block not initialized");
  169. throw D3DERR_INVALIDCALL;
  170. }
  171. pStateSet->Capture(pDevI, TRUE);
  172. if (pStateSet->m_dwDeviceHandle != __INVALIDHANDLE)
  173. {
  174. pStateSet->Capture(pDevI, FALSE);
  175. pDevI->m_pDDI->InsertStateSetOp(D3DHAL_STATESETCAPTURE,
  176. pStateSet->m_dwDeviceHandle,
  177. (D3DSTATEBLOCKTYPE)0);
  178. }
  179. }
  180. //---------------------------------------------------------------------
  181. #undef DPF_MODNAME
  182. #define DPF_MODNAME "CStateSets::CreatePredefined"
  183. void CStateSets::CreatePredefined(CD3DBase *pDevI, D3DSTATEBLOCKTYPE sbt)
  184. {
  185. if (StartNewSet() != D3D_OK)
  186. throw E_OUTOFMEMORY;
  187. m_pCurrentStateSet->CreatePredefined(pDevI, sbt);
  188. }
  189. //---------------------------------------------------------------------
  190. // Allocates device handle if necessary
  191. // And returns information of the device buffer
  192. //
  193. #undef DPF_MODNAME
  194. #define DPF_MODNAME "CStateSets::GetDeviceBufferInfo"
  195. void CStateSets::GetDeviceBufferInfo(DWORD* dwStateSetHandle,
  196. LPVOID *pBuffer,
  197. DWORD* dwBufferSize)
  198. {
  199. if (m_pCurrentStateSet->m_DriverBuffer.m_dwCurrentSize != 0)
  200. {
  201. // Allocate a handle for the device
  202. m_pCurrentStateSet->m_dwDeviceHandle = m_DeviceHandles.CreateNewHandle( NULL );
  203. if (m_pCurrentStateSet->m_dwDeviceHandle == __INVALIDHANDLE)
  204. {
  205. D3D_ERR("Cannot allocate device handle for a state block");
  206. throw E_OUTOFMEMORY;
  207. }
  208. }
  209. *dwStateSetHandle = m_pCurrentStateSet->m_dwDeviceHandle;
  210. *pBuffer = (LPVOID)m_pCurrentStateSet->m_DriverBuffer.m_pBuffer;
  211. *dwBufferSize = m_pCurrentStateSet->m_DriverBuffer.m_dwCurrentSize;
  212. }
  213. //---------------------------------------------------------------------
  214. #undef DPF_MODNAME
  215. #define DPF_MODNAME "CStateSets::GetDeviceBufferInfo"
  216. void CStateSets::CreateNewDeviceHandle(DWORD* dwStateSetHandle)
  217. {
  218. // Allocate a handle for the device
  219. m_pCurrentStateSet->m_dwDeviceHandle = m_DeviceHandles.CreateNewHandle( NULL );
  220. if (m_pCurrentStateSet->m_dwDeviceHandle == __INVALIDHANDLE)
  221. {
  222. D3D_ERR("Cannot allocate device handle for a state block");
  223. throw E_OUTOFMEMORY;
  224. }
  225. *dwStateSetHandle = m_pCurrentStateSet->m_dwDeviceHandle;
  226. }
  227. //---------------------------------------------------------------------
  228. #undef DPF_MODNAME
  229. #define DPF_MODNAME "CStateSet::TranslateDeviceBufferToDX7DDI"
  230. void CStateSets::TranslateDeviceBufferToDX7DDI( DWORD* p, DWORD dwSize )
  231. {
  232. DWORD* pEnd = (DWORD*)((BYTE*)p + dwSize);
  233. while (p < pEnd)
  234. {
  235. LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
  236. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  237. switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
  238. {
  239. case D3DDP2OP_RENDERSTATE:
  240. {
  241. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  242. {
  243. D3DRENDERSTATETYPE dwState = (D3DRENDERSTATETYPE)*p++;
  244. DWORD dwValue = *p++;
  245. }
  246. }
  247. break;
  248. case D3DDP2OP_SETLIGHT:
  249. {
  250. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  251. {
  252. LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p;
  253. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETLIGHT));
  254. switch (pData->dwDataType)
  255. {
  256. case D3DHAL_SETLIGHT_ENABLE:
  257. case D3DHAL_SETLIGHT_DISABLE:
  258. break;
  259. case D3DHAL_SETLIGHT_DATA:
  260. p = (LPDWORD)((LPBYTE)p + sizeof(D3DLIGHT8));
  261. break;
  262. }
  263. }
  264. break;
  265. }
  266. case D3DDP2OP_SETMATERIAL:
  267. {
  268. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  269. {
  270. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETMATERIAL));
  271. }
  272. break;
  273. }
  274. case D3DDP2OP_SETTRANSFORM:
  275. {
  276. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  277. {
  278. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETTRANSFORM));
  279. }
  280. break;
  281. }
  282. case D3DDP2OP_TEXTURESTAGESTATE:
  283. {
  284. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  285. {
  286. LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
  287. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
  288. // Map DX8 filter enums to DX6/7 enums
  289. switch (pData->TSState)
  290. {
  291. case D3DTSS_MAGFILTER: pData->dwValue = texf2texfg[min(D3DTEXF_GAUSSIANCUBIC,pData->dwValue)]; break;
  292. case D3DTSS_MINFILTER: pData->dwValue = texf2texfn[min(D3DTEXF_GAUSSIANCUBIC,pData->dwValue)]; break;
  293. case D3DTSS_MIPFILTER: pData->dwValue = texf2texfp[min(D3DTEXF_GAUSSIANCUBIC,pData->dwValue)]; break;
  294. }
  295. }
  296. break;
  297. }
  298. case D3DDP2OP_VIEWPORTINFO:
  299. {
  300. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  301. {
  302. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VIEWPORTINFO));
  303. // The next command has to be D3DDP2OP_ZRANGE
  304. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  305. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2ZRANGE));
  306. }
  307. break;
  308. }
  309. case D3DDP2OP_SETCLIPPLANE:
  310. {
  311. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  312. {
  313. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETCLIPPLANE));
  314. }
  315. break;
  316. }
  317. #ifdef DBG
  318. default:
  319. DXGASSERT(FALSE);
  320. #endif
  321. }
  322. }
  323. }
  324. //---------------------------------------------------------------------
  325. #undef DPF_MODNAME
  326. #define DPF_MODNAME "CStateSets::InsertRenderState"
  327. void CStateSets::InsertRenderState(D3DRENDERSTATETYPE state, DWORD dwValue,
  328. BOOL bDriverCanHandle)
  329. {
  330. struct
  331. {
  332. D3DRENDERSTATETYPE state;
  333. DWORD dwValue;
  334. } data = {state, dwValue};
  335. m_pCurrentStateSet->InsertCommand(D3DDP2OP_RENDERSTATE,
  336. &data, sizeof(data),
  337. !m_bEmulate && bDriverCanHandle);
  338. }
  339. //---------------------------------------------------------------------
  340. #undef DPF_MODNAME
  341. #define DPF_MODNAME "CStateSets::InsertLight"
  342. void CStateSets::InsertLight(DWORD dwLightIndex, CONST D3DLIGHT8* pData)
  343. {
  344. struct
  345. {
  346. D3DHAL_DP2SETLIGHT header;
  347. D3DLIGHT8 light;
  348. } data;
  349. data.header.dwIndex = dwLightIndex;
  350. data.header.dwDataType = D3DHAL_SETLIGHT_DATA;
  351. data.light= *pData;
  352. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETLIGHT, &data, sizeof(data),
  353. !m_bEmulate && m_bTLHal);
  354. }
  355. //---------------------------------------------------------------------
  356. #undef DPF_MODNAME
  357. #define DPF_MODNAME "CStateSets::InsertLightEnable"
  358. void CStateSets::InsertLightEnable(DWORD dwLightIndex, BOOL bEnable)
  359. {
  360. D3DHAL_DP2SETLIGHT data;
  361. data.dwIndex = dwLightIndex;
  362. if (bEnable)
  363. data.dwDataType = D3DHAL_SETLIGHT_ENABLE;
  364. else
  365. data.dwDataType = D3DHAL_SETLIGHT_DISABLE;
  366. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETLIGHT, &data, sizeof(data),
  367. !m_bEmulate && m_bTLHal);
  368. }
  369. //---------------------------------------------------------------------
  370. #undef DPF_MODNAME
  371. #define DPF_MODNAME "CStateSets::InsertViewport"
  372. void CStateSets::InsertViewport(CONST D3DVIEWPORT8* lpVwpData)
  373. {
  374. D3DHAL_DP2VIEWPORTINFO data2;
  375. data2.dwX = lpVwpData->X;
  376. data2.dwY = lpVwpData->Y;
  377. data2.dwWidth = lpVwpData->Width;
  378. data2.dwHeight = lpVwpData->Height;
  379. m_pCurrentStateSet->InsertCommand(D3DDP2OP_VIEWPORTINFO, &data2, sizeof(data2),
  380. !m_bEmulate && m_bTLHal);
  381. D3DHAL_DP2ZRANGE data1;
  382. data1.dvMinZ = lpVwpData->MinZ;
  383. data1.dvMaxZ = lpVwpData->MaxZ;
  384. m_pCurrentStateSet->InsertCommand(D3DDP2OP_ZRANGE, &data1, sizeof(data1),
  385. !m_bEmulate && m_bTLHal);
  386. m_pCurrentStateSet->ResetCurrentCommand();
  387. }
  388. //---------------------------------------------------------------------
  389. #undef DPF_MODNAME
  390. #define DPF_MODNAME "CStateSets::InsertMaterial"
  391. void CStateSets::InsertMaterial(CONST D3DMATERIAL8* pData)
  392. {
  393. D3DMATERIAL8 mat = *pData;
  394. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETMATERIAL,
  395. &mat,
  396. sizeof(D3DMATERIAL8),
  397. !m_bEmulate && m_bTLHal);
  398. m_pCurrentStateSet->ResetCurrentCommand();
  399. }
  400. //---------------------------------------------------------------------
  401. #undef DPF_MODNAME
  402. #define DPF_MODNAME "CStateSets::InsertClipPlane"
  403. void CStateSets::InsertClipPlane(DWORD dwPlaneIndex,
  404. CONST D3DVALUE* pPlaneEquation)
  405. {
  406. D3DHAL_DP2SETCLIPPLANE data;
  407. data.dwIndex = dwPlaneIndex;
  408. data.plane[0] = pPlaneEquation[0];
  409. data.plane[1] = pPlaneEquation[1];
  410. data.plane[2] = pPlaneEquation[2];
  411. data.plane[3] = pPlaneEquation[3];
  412. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETCLIPPLANE,
  413. &data, sizeof(data),
  414. !m_bEmulate && m_bTLHal);
  415. }
  416. //---------------------------------------------------------------------
  417. #undef DPF_MODNAME
  418. #define DPF_MODNAME "CStateSets::InsertTransform"
  419. void CStateSets::InsertTransform(D3DTRANSFORMSTATETYPE state,
  420. CONST D3DMATRIX* lpMat)
  421. {
  422. D3DHAL_DP2SETTRANSFORM data;
  423. data.xfrmType = state;
  424. data.matrix = *lpMat;
  425. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETTRANSFORM,
  426. &data, sizeof(data),
  427. !m_bEmulate && m_bTLHal);
  428. }
  429. //---------------------------------------------------------------------
  430. #undef DPF_MODNAME
  431. #define DPF_MODNAME "CStateSets::InsertTextureStageState"
  432. void CStateSets::InsertTextureStageState(DWORD dwStage,
  433. D3DTEXTURESTAGESTATETYPE type,
  434. DWORD dwValue)
  435. {
  436. D3DHAL_DP2TEXTURESTAGESTATE data = {(WORD)dwStage, type, dwValue};
  437. m_pCurrentStateSet->InsertCommand(D3DDP2OP_TEXTURESTAGESTATE,
  438. &data, sizeof(data),
  439. !m_bEmulate);
  440. }
  441. //---------------------------------------------------------------------
  442. #undef DPF_MODNAME
  443. #define DPF_MODNAME "CStateSets::InsertTexture"
  444. void CStateSets::InsertTexture(DWORD dwStage, IDirect3DBaseTexture8 *pTex)
  445. {
  446. D3DHAL_DP2FRONTENDDATA data = {(WORD)dwStage, pTex};
  447. // Up the internal refcount of this texture.
  448. CBaseTexture *lpTexI = CBaseTexture::SafeCast(pTex);
  449. if (lpTexI)
  450. lpTexI->IncrementUseCount();
  451. // Only the front-end will parse this instruction
  452. m_pCurrentStateSet->InsertCommand((D3DHAL_DP2OPERATION)D3DDP2OP_FRONTENDDATA, &data, sizeof(data), FALSE);
  453. }
  454. //---------------------------------------------------------------------
  455. #undef DPF_MODNAME
  456. #define DPF_MODNAME "CStateSets::InsertCurrentTexturePalette"
  457. void CStateSets::InsertCurrentTexturePalette(DWORD PaletteNumber)
  458. {
  459. D3DHAL_DP2FESETPAL data = {PaletteNumber};
  460. // Only the front-end will parse this instruction
  461. m_pCurrentStateSet->InsertCommand((D3DHAL_DP2OPERATION)D3DDP2OP_FESETPAL, &data, sizeof(data), FALSE);
  462. }
  463. //---------------------------------------------------------------------
  464. #undef DPF_MODNAME
  465. #define DPF_MODNAME "CStateSets::InsertVertexShader"
  466. void CStateSets::InsertVertexShader(DWORD dwShaderHandle, BOOL bHardware)
  467. {
  468. D3DHAL_DP2VERTEXSHADER data = {dwShaderHandle};
  469. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETVERTEXSHADER,
  470. &data, sizeof(data),
  471. !m_bEmulate && m_bHardwareVP &&
  472. m_bDX8Dev && bHardware);
  473. }
  474. //---------------------------------------------------------------------
  475. #undef DPF_MODNAME
  476. #define DPF_MODNAME "CStateSets::InsertPixelShader"
  477. void CStateSets::InsertPixelShader(DWORD dwShaderHandle)
  478. {
  479. D3DHAL_DP2PIXELSHADER data = {dwShaderHandle};
  480. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETPIXELSHADER,
  481. &data, sizeof(data),
  482. !m_bEmulate && m_bDX8Dev);
  483. }
  484. //---------------------------------------------------------------------
  485. #undef DPF_MODNAME
  486. #define DPF_MODNAME "CStateSets::InsertStreamSource"
  487. void CStateSets::InsertStreamSource(DWORD dwStream, CVertexBuffer *pBuf, DWORD dwStride)
  488. {
  489. D3DHAL_DP2FESETVB data = {(WORD)dwStream, pBuf, dwStride};
  490. // Only the front-end will parse this instruction
  491. CVertexBuffer* pVB = static_cast<CVertexBuffer*>(pBuf);
  492. if (pVB)
  493. pVB->IncrementUseCount();
  494. m_pCurrentStateSet->InsertCommand((D3DHAL_DP2OPERATION)D3DDP2OP_FESETVB, &data, sizeof(data), FALSE);
  495. }
  496. //---------------------------------------------------------------------
  497. #undef DPF_MODNAME
  498. #define DPF_MODNAME "CStateSets::InsertIndices"
  499. void CStateSets::InsertIndices(CIndexBuffer *pBuf, DWORD dwBaseVertex)
  500. {
  501. D3DHAL_DP2FESETIB data = {pBuf, dwBaseVertex};
  502. // Only the front-end will parse this instruction
  503. CIndexBuffer* pIB = static_cast<CIndexBuffer*>(pBuf);
  504. if (pIB)
  505. pIB->IncrementUseCount();
  506. m_pCurrentStateSet->InsertCommand((D3DHAL_DP2OPERATION)D3DDP2OP_FESETIB, &data, sizeof(data), FALSE);
  507. }
  508. //---------------------------------------------------------------------
  509. #undef DPF_MODNAME
  510. #define DPF_MODNAME "CStateSets::InsertVertexShaderConstant"
  511. void CStateSets::InsertVertexShaderConstant(DWORD Register, CONST VOID* pConstantData, DWORD ConstantCount)
  512. {
  513. LPVOID pData = new BYTE[sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + ConstantCount * 16];
  514. if(pData == 0)
  515. {
  516. throw E_OUTOFMEMORY;
  517. }
  518. ((LPD3DHAL_DP2SETVERTEXSHADERCONST)pData)->dwRegister = Register;
  519. ((LPD3DHAL_DP2SETVERTEXSHADERCONST)pData)->dwCount = ConstantCount;
  520. memcpy((LPD3DHAL_DP2SETVERTEXSHADERCONST)pData + 1, pConstantData, ConstantCount * 16);
  521. try
  522. {
  523. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETVERTEXSHADERCONST,
  524. pData,
  525. sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + ConstantCount * 16,
  526. !m_bEmulate && m_bDX8Dev && m_bTLHal);
  527. }
  528. catch(HRESULT hr)
  529. {
  530. delete[] pData;
  531. throw hr;
  532. }
  533. delete[] pData;
  534. }
  535. //---------------------------------------------------------------------
  536. #undef DPF_MODNAME
  537. #define DPF_MODNAME "CStateSets::InsertPixelShaderConstant"
  538. void CStateSets::InsertPixelShaderConstant(DWORD Register,
  539. CONST VOID* pConstantData,
  540. DWORD ConstantCount)
  541. {
  542. LPVOID pData = new BYTE[sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + ConstantCount * 16];
  543. if(pData == 0)
  544. {
  545. throw E_OUTOFMEMORY;
  546. }
  547. ((LPD3DHAL_DP2SETPIXELSHADERCONST)pData)->dwRegister = Register;
  548. ((LPD3DHAL_DP2SETPIXELSHADERCONST)pData)->dwCount = ConstantCount;
  549. memcpy((LPD3DHAL_DP2SETPIXELSHADERCONST)pData + 1, pConstantData, ConstantCount * 16);
  550. try
  551. {
  552. m_pCurrentStateSet->InsertCommand(D3DDP2OP_SETPIXELSHADERCONST,
  553. pData,
  554. sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + ConstantCount * 16,
  555. !m_bEmulate && m_bDX8Dev);
  556. }
  557. catch(HRESULT hr)
  558. {
  559. delete[] pData;
  560. throw hr;
  561. }
  562. delete[] pData;
  563. }
  564. //---------------------------------------------------------------------
  565. #undef DPF_MODNAME
  566. #define DPF_MODNAME "CStateSets::Execute"
  567. void CStateSets::Execute(CD3DBase *pDevI, DWORD dwHandle)
  568. {
  569. #if DBG
  570. if (dwHandle >= m_dwMaxSets)
  571. {
  572. D3D_ERR("Invalid state block handle");
  573. throw D3DERR_INVALIDCALL;
  574. }
  575. #endif
  576. CStateSet *pStateSet = &m_pStateSets[dwHandle];
  577. #if DBG
  578. if (!(pStateSet->m_dwStateSetFlags & __STATESET_INITIALIZED))
  579. {
  580. D3D_ERR("State block not initialized");
  581. throw D3DERR_INVALIDCALL;
  582. }
  583. #endif
  584. // Parse recorded data first
  585. pStateSet->Execute(pDevI, TRUE);
  586. // If the hardware buffer is not empty, we pass recorded data to it
  587. if (pStateSet->m_dwDeviceHandle != __INVALIDHANDLE)
  588. {
  589. pStateSet->Execute(pDevI, FALSE);
  590. if((pDevI->m_dwRuntimeFlags & D3DRT_RSSOFTWAREPROCESSING) == 0 || (pStateSet->m_dwStateSetFlags & __STATESET_HASONLYVERTEXSTATE) == 0)
  591. {
  592. pDevI->m_pDDI->InsertStateSetOp(D3DHAL_STATESETEXECUTE, pStateSet->m_dwDeviceHandle, (D3DSTATEBLOCKTYPE)0);
  593. }
  594. else
  595. {
  596. pStateSet->m_dwStateSetFlags &= ~__STATESET_HASONLYVERTEXSTATE;
  597. }
  598. }
  599. }
  600. //=====================================================================
  601. // CStateSet interface
  602. //
  603. #undef DPF_MODNAME
  604. #define DPF_MODNAME "CStateSet::Release"
  605. HRESULT CStateSet::Release()
  606. {
  607. if (!(m_dwStateSetFlags & __STATESET_INITIALIZED))
  608. return D3DERR_INVALIDCALL;
  609. m_dwStateSetFlags &= ~__STATESET_INITIALIZED;
  610. // Parse the FEOnly buffer and release all the VB/IB/Texture handles.
  611. DWORD *p;
  612. DWORD dwSize;
  613. DWORD *pEnd;
  614. p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
  615. dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
  616. pEnd = (DWORD*)((BYTE*)p + dwSize);
  617. while (p < pEnd)
  618. {
  619. LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
  620. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  621. switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
  622. {
  623. case D3DDP2OP_RENDERSTATE:
  624. p = (DWORD *)((D3DHAL_DP2RENDERSTATE *)p + pCommand->wStateCount);
  625. break;
  626. case D3DDP2OP_SETLIGHT:
  627. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  628. {
  629. LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p;
  630. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETLIGHT));
  631. switch (pData->dwDataType)
  632. {
  633. case D3DHAL_SETLIGHT_ENABLE:
  634. case D3DHAL_SETLIGHT_DISABLE:
  635. break;
  636. case D3DHAL_SETLIGHT_DATA:
  637. p = (DWORD *)((BYTE *)p + sizeof(D3DLIGHT8));
  638. break;
  639. }
  640. }
  641. break;
  642. case D3DDP2OP_SETMATERIAL:
  643. p = (DWORD *)((D3DHAL_DP2SETMATERIAL *)p + pCommand->wStateCount);
  644. break;
  645. case D3DDP2OP_SETTRANSFORM:
  646. p = (DWORD *)((D3DHAL_DP2SETTRANSFORM *)p + pCommand->wStateCount);
  647. break;
  648. case D3DDP2OP_TEXTURESTAGESTATE:
  649. p = (DWORD *)((D3DHAL_DP2TEXTURESTAGESTATE *)p +
  650. pCommand->wStateCount);
  651. break;
  652. case D3DDP2OP_FRONTENDDATA:
  653. {
  654. CBaseTexture* pTexOld = NULL;
  655. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  656. {
  657. LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
  658. pTexOld = CBaseTexture::SafeCast(pData->pTexture);
  659. if( pTexOld )
  660. pTexOld->DecrementUseCount();
  661. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
  662. }
  663. break;
  664. }
  665. case D3DDP2OP_FESETVB:
  666. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  667. {
  668. LPD3DHAL_DP2FESETVB pData = (LPD3DHAL_DP2FESETVB)p;
  669. if( pData->pBuf )
  670. pData->pBuf->DecrementUseCount();
  671. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETVB));
  672. }
  673. break;
  674. case D3DDP2OP_FESETIB:
  675. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  676. {
  677. LPD3DHAL_DP2FESETIB pData = (LPD3DHAL_DP2FESETIB)p;
  678. if( pData->pBuf )
  679. pData->pBuf->DecrementUseCount();
  680. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETIB));
  681. }
  682. break;
  683. case D3DDP2OP_FESETPAL:
  684. p = (DWORD *)((D3DHAL_DP2FESETPAL *)p + pCommand->wStateCount);
  685. break;
  686. case D3DDP2OP_VIEWPORTINFO:
  687. // The next command has to be D3DDP2OP_ZRANGE
  688. p = (DWORD *)((BYTE *)p +
  689. ( sizeof(D3DHAL_DP2VIEWPORTINFO) +
  690. sizeof(D3DHAL_DP2COMMAND) +
  691. sizeof(D3DHAL_DP2ZRANGE ) ) *
  692. pCommand->wStateCount );
  693. break;
  694. case D3DDP2OP_SETCLIPPLANE:
  695. p = (DWORD *)((D3DHAL_DP2SETCLIPPLANE *)p + pCommand->wStateCount);
  696. break;
  697. case D3DDP2OP_SETVERTEXSHADER:
  698. p = (DWORD *)((D3DHAL_DP2VERTEXSHADER *)p + pCommand->wStateCount);
  699. break;
  700. case D3DDP2OP_SETPIXELSHADER:
  701. p = (DWORD *)((D3DHAL_DP2PIXELSHADER *)p + pCommand->wStateCount);
  702. break;
  703. case D3DDP2OP_SETVERTEXSHADERCONST:
  704. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  705. {
  706. LPD3DHAL_DP2SETVERTEXSHADERCONST pData = (LPD3DHAL_DP2SETVERTEXSHADERCONST)p;
  707. p = (DWORD*)((BYTE*)p +
  708. sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) +
  709. pData->dwCount * 16);
  710. }
  711. break;
  712. case D3DDP2OP_SETPIXELSHADERCONST:
  713. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  714. {
  715. LPD3DHAL_DP2SETPIXELSHADERCONST pData = (LPD3DHAL_DP2SETPIXELSHADERCONST)p;
  716. p = (DWORD*)((BYTE*)p +
  717. sizeof(D3DHAL_DP2SETPIXELSHADERCONST) +
  718. pData->dwCount * 16);
  719. }
  720. break;
  721. #ifdef DBG
  722. default:
  723. DXGASSERT(FALSE);
  724. #endif
  725. }
  726. }
  727. m_FEOnlyBuffer.Reset();
  728. m_DriverBuffer.Reset();
  729. return D3D_OK;
  730. }
  731. //---------------------------------------------------------------------
  732. #undef DPF_MODNAME
  733. #define DPF_MODNAME "CStateSet::InsertCommand"
  734. void CStateSet::InsertCommand(D3DHAL_DP2OPERATION op, LPVOID pData,
  735. DWORD dwDataSize,
  736. BOOL bDriverCanHandle)
  737. {
  738. if (op == D3DDP2OP_TEXTURESTAGESTATE ||
  739. (op == D3DDP2OP_RENDERSTATE &&
  740. ((LPD3DHAL_DP2RENDERSTATE)pData)->RenderState >= D3DRENDERSTATE_WRAP0 &&
  741. ((LPD3DHAL_DP2RENDERSTATE)pData)->RenderState <= D3DRENDERSTATE_WRAP7))
  742. {
  743. m_dwStateSetFlags |= __STATESET_NEEDCHECKREMAPPING;
  744. }
  745. if (bDriverCanHandle)
  746. m_DriverBuffer.InsertCommand(op, pData, dwDataSize);
  747. else
  748. m_FEOnlyBuffer.InsertCommand(op, pData, dwDataSize);
  749. }
  750. //---------------------------------------------------------------------
  751. #undef DPF_MODNAME
  752. #define DPF_MODNAME "CStateSet::Execute"
  753. void CStateSet::Execute(CD3DBase *pBaseDev, BOOL bFrontEndBuffer)
  754. {
  755. DWORD *p;
  756. DWORD dwSize;
  757. DWORD *pEnd;
  758. // The device is not pure, so we can cast
  759. DXGASSERT((pBaseDev->BehaviorFlags() & D3DCREATE_PUREDEVICE) == 0);
  760. CD3DHal *pDevI = static_cast<CD3DHal*>(pBaseDev);
  761. D3DFE_PROCESSVERTICES* pv = pDevI->m_pv;
  762. try
  763. {
  764. // Texture stages could be re-mapped during texture transform processing.
  765. // Before we set new values we have to restore original ones
  766. if (pv->dwDeviceFlags & D3DDEV_REMAPTEXTUREINDICES &&
  767. m_dwStateSetFlags & __STATESET_NEEDCHECKREMAPPING)
  768. {
  769. RestoreTextureStages(pDevI);
  770. pDevI->ForceFVFRecompute();
  771. }
  772. if (bFrontEndBuffer)
  773. {
  774. p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
  775. dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
  776. }
  777. else
  778. {
  779. p = (DWORD*)m_DriverBuffer.m_pBuffer;
  780. dwSize = m_DriverBuffer.m_dwCurrentSize;
  781. pDevI->m_dwRuntimeFlags |= D3DRT_EXECUTESTATEMODE;
  782. m_dwStateSetFlags |= __STATESET_HASONLYVERTEXSTATE;
  783. }
  784. pEnd = (DWORD*)((BYTE*)p + dwSize);
  785. while (p < pEnd)
  786. {
  787. LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
  788. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  789. switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
  790. {
  791. case D3DDP2OP_RENDERSTATE:
  792. {
  793. if(pDevI->m_dwRuntimeFlags & D3DRT_EXECUTESTATEMODE)
  794. {
  795. m_dwStateSetFlags &= ~__STATESET_HASONLYVERTEXSTATE;
  796. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  797. {
  798. D3DRENDERSTATETYPE dwState = (D3DRENDERSTATETYPE)*p++;
  799. DWORD dwValue = *p++;
  800. if ( (pDevI->rstates[dwState] != dwValue)
  801. #if DBG
  802. && (dwState != D3DRS_DEBUGMONITORTOKEN) // don't filter these
  803. #endif
  804. )
  805. {
  806. if (!pDevI->rsVec.IsBitSet(dwState))
  807. { // Fast path. We do not need any processing done in UpdateInternalState other than updating rstates array
  808. pDevI->rstates[dwState] = dwValue;
  809. }
  810. else
  811. {
  812. pDevI->UpdateInternalState(dwState, dwValue);
  813. }
  814. }
  815. else
  816. {
  817. D3D_WARN(4,"Ignoring redundant SetRenderState %d", dwState);
  818. }
  819. }
  820. }
  821. else
  822. {
  823. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  824. {
  825. D3DRENDERSTATETYPE dwState = (D3DRENDERSTATETYPE)*p++;
  826. DWORD dwValue = *p++;
  827. if ( (pDevI->rstates[dwState] != dwValue)
  828. #if DBG
  829. && (dwState != D3DRS_DEBUGMONITORTOKEN) // don't filter these
  830. #endif
  831. )
  832. {
  833. if (!pDevI->rsVec.IsBitSet(dwState))
  834. { // Fast path. We do not need any processing done in UpdateInternalState other than updating rstates array
  835. pDevI->rstates[dwState] = dwValue;
  836. pDevI->m_pDDI->SetRenderState(dwState, dwValue);
  837. }
  838. else
  839. {
  840. pDevI->UpdateInternalState(dwState, dwValue);
  841. // Vertex processing only render states will be passed to the
  842. // driver when we switch to the hardware vertex processing mode
  843. if ((!(pDevI->rsVertexProcessingOnly.IsBitSet(dwState) &&
  844. pDevI->m_dwRuntimeFlags & D3DRT_RSSOFTWAREPROCESSING)))
  845. {
  846. if (pDevI->CanHandleRenderState(dwState))
  847. {
  848. pDevI->m_pDDI->SetRenderState(dwState, dwValue);
  849. }
  850. }
  851. }
  852. }
  853. else
  854. {
  855. D3D_WARN(4,"Ignoring redundant SetRenderState %d", dwState);
  856. }
  857. }
  858. }
  859. break;
  860. }
  861. case D3DDP2OP_SETLIGHT:
  862. {
  863. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  864. {
  865. LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p;
  866. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETLIGHT));
  867. switch (pData->dwDataType)
  868. {
  869. case D3DHAL_SETLIGHT_ENABLE:
  870. pDevI->LightEnableI( pData->dwIndex, TRUE );
  871. break;
  872. case D3DHAL_SETLIGHT_DISABLE:
  873. pDevI->LightEnableI( pData->dwIndex, FALSE );
  874. break;
  875. case D3DHAL_SETLIGHT_DATA:
  876. pDevI->SetLightI(pData->dwIndex, (D3DLIGHT8 *)p);
  877. p = (LPDWORD)((LPBYTE)p + sizeof(D3DLIGHT8));
  878. break;
  879. }
  880. }
  881. break;
  882. }
  883. case D3DDP2OP_SETMATERIAL:
  884. {
  885. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  886. {
  887. LPD3DHAL_DP2SETMATERIAL pData = (LPD3DHAL_DP2SETMATERIAL)p;
  888. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETMATERIAL));
  889. pDevI->SetMaterialFast((D3DMATERIAL8*)pData);
  890. }
  891. break;
  892. }
  893. case D3DDP2OP_SETTRANSFORM:
  894. {
  895. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  896. {
  897. D3DHAL_DP2SETTRANSFORM *pData = (D3DHAL_DP2SETTRANSFORM*)p;
  898. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETTRANSFORM));
  899. pDevI->SetTransformI(pData->xfrmType, &pData->matrix);
  900. }
  901. break;
  902. }
  903. case D3DDP2OP_TEXTURESTAGESTATE:
  904. {
  905. if (pDevI->m_dwRuntimeFlags & D3DRT_EXECUTESTATEMODE)
  906. {
  907. m_dwStateSetFlags &= ~__STATESET_HASONLYVERTEXSTATE;
  908. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  909. {
  910. LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
  911. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
  912. DWORD dwStage = pData->wStage;
  913. DWORD dwState = pData->TSState;
  914. DWORD dwValue = pData->dwValue;
  915. if (pDevI->tsstates[dwStage][dwState] != dwValue)
  916. {
  917. // Fast path. We do not need any processing done in UpdateInternalTSS other than updating tsstates array
  918. if (pDevI->NeedInternalTSSUpdate(dwState))
  919. {
  920. pDevI->UpdateInternalTextureStageState(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, &dwValue);
  921. }
  922. else
  923. {
  924. pDevI->tsstates[dwStage][dwState] = dwValue;
  925. }
  926. }
  927. else
  928. {
  929. D3D_WARN(4,"Ignoring redundant SetTextureStageState Stage: %d, State: %d", dwStage, dwState);
  930. }
  931. }
  932. }
  933. else
  934. {
  935. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  936. {
  937. LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
  938. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
  939. DWORD dwStage = pData->wStage;
  940. DWORD dwState = pData->TSState;
  941. DWORD dwValue = pData->dwValue;
  942. if (pDevI->tsstates[dwStage][dwState] != dwValue)
  943. {
  944. // Fast path. We do not need any processing done in UpdateInternalTSS other than updating tsstates array
  945. if (pDevI->NeedInternalTSSUpdate(dwState))
  946. {
  947. if(pDevI->UpdateInternalTextureStageState(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, &dwValue))
  948. continue;
  949. }
  950. else
  951. {
  952. pDevI->tsstates[dwStage][dwState] = dwValue;
  953. }
  954. if (dwStage >= pDevI->m_dwMaxTextureBlendStages)
  955. continue;
  956. pDevI->m_pDDI->SetTSS(dwStage, (D3DTEXTURESTAGESTATETYPE)dwState, dwValue);
  957. }
  958. else
  959. {
  960. D3D_WARN(4,"Ignoring redundant SetTextureStageState Stage: %d, State: %d", dwStage, dwState);
  961. }
  962. }
  963. }
  964. break;
  965. }
  966. case D3DDP2OP_FRONTENDDATA:
  967. {
  968. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  969. {
  970. LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
  971. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
  972. HRESULT ret = pDevI->SetTexture(pData->wStage, pData->pTexture);
  973. if (ret != D3D_OK)
  974. throw ret;
  975. }
  976. break;
  977. }
  978. case D3DDP2OP_FESETVB:
  979. {
  980. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  981. {
  982. LPD3DHAL_DP2FESETVB pData = (LPD3DHAL_DP2FESETVB)p;
  983. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETVB));
  984. HRESULT ret = pDevI->SetStreamSource(pData->wStream, pData->pBuf, pData->dwStride);
  985. if (ret != D3D_OK)
  986. throw ret;
  987. }
  988. break;
  989. }
  990. case D3DDP2OP_FESETIB:
  991. {
  992. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  993. {
  994. LPD3DHAL_DP2FESETIB pData = (LPD3DHAL_DP2FESETIB)p;
  995. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETIB));
  996. HRESULT ret = pDevI->SetIndices(pData->pBuf, pData->dwBase);
  997. if (ret != D3D_OK)
  998. throw ret;
  999. }
  1000. break;
  1001. }
  1002. case D3DDP2OP_FESETPAL:
  1003. {
  1004. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1005. {
  1006. LPD3DHAL_DP2FESETPAL pData = (LPD3DHAL_DP2FESETPAL)p;
  1007. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETPAL));
  1008. if( pData->dwPaletteNumber != __INVALIDPALETTE )
  1009. {
  1010. HRESULT ret = pDevI->SetCurrentTexturePalette(pData->dwPaletteNumber);
  1011. if (ret != D3D_OK)
  1012. throw ret;
  1013. }
  1014. }
  1015. break;
  1016. }
  1017. case D3DDP2OP_VIEWPORTINFO:
  1018. {
  1019. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1020. {
  1021. D3DVIEWPORT8 viewport;
  1022. LPD3DHAL_DP2VIEWPORTINFO lpVwpData = (LPD3DHAL_DP2VIEWPORTINFO)p;
  1023. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VIEWPORTINFO));
  1024. viewport.X = lpVwpData->dwX;
  1025. viewport.Y = lpVwpData->dwY;
  1026. viewport.Width = lpVwpData->dwWidth;
  1027. viewport.Height = lpVwpData->dwHeight;
  1028. // The next command has to be D3DDP2OP_ZRANGE
  1029. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  1030. LPD3DHAL_DP2ZRANGE pData = (LPD3DHAL_DP2ZRANGE)p;
  1031. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2ZRANGE));
  1032. viewport.MinZ = pData->dvMinZ;
  1033. viewport.MaxZ = pData->dvMaxZ;
  1034. pDevI->SetViewportI(&viewport);
  1035. }
  1036. break;
  1037. }
  1038. case D3DDP2OP_SETCLIPPLANE:
  1039. {
  1040. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1041. {
  1042. D3DHAL_DP2SETCLIPPLANE *pData = (D3DHAL_DP2SETCLIPPLANE*)p;
  1043. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETCLIPPLANE));
  1044. pDevI->SetClipPlaneI(pData->dwIndex, pData->plane);
  1045. }
  1046. break;
  1047. }
  1048. case D3DDP2OP_SETVERTEXSHADER:
  1049. {
  1050. // Optimization, dont loop, use the last one.
  1051. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1052. {
  1053. LPD3DHAL_DP2VERTEXSHADER pData = (LPD3DHAL_DP2VERTEXSHADER)p;
  1054. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VERTEXSHADER));
  1055. if( pData->dwHandle != 0 )
  1056. {
  1057. pDevI->SetVertexShader(pData->dwHandle);
  1058. }
  1059. else
  1060. {
  1061. pDevI->m_dwCurrentShaderHandle = 0;
  1062. }
  1063. }
  1064. pDevI->m_pDDI->ResetVertexShader();
  1065. break;
  1066. }
  1067. case D3DDP2OP_SETPIXELSHADER:
  1068. {
  1069. m_dwStateSetFlags &= ~__STATESET_HASONLYVERTEXSTATE;
  1070. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1071. {
  1072. LPD3DHAL_DP2PIXELSHADER pData = (LPD3DHAL_DP2PIXELSHADER)p;
  1073. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2PIXELSHADER));
  1074. pDevI->SetPixelShaderFast(pData->dwHandle);
  1075. }
  1076. break;
  1077. }
  1078. case D3DDP2OP_SETVERTEXSHADERCONST:
  1079. {
  1080. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1081. {
  1082. LPD3DHAL_DP2SETVERTEXSHADERCONST pData = (LPD3DHAL_DP2SETVERTEXSHADERCONST)p;
  1083. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + pData->dwCount * 16);
  1084. pDevI->SetVertexShaderConstantI(pData->dwRegister, pData + 1, pData->dwCount);
  1085. }
  1086. break;
  1087. }
  1088. case D3DDP2OP_SETPIXELSHADERCONST:
  1089. {
  1090. m_dwStateSetFlags &= ~__STATESET_HASONLYVERTEXSTATE;
  1091. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1092. {
  1093. LPD3DHAL_DP2SETPIXELSHADERCONST pData = (LPD3DHAL_DP2SETPIXELSHADERCONST)p;
  1094. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + pData->dwCount * 16);
  1095. pDevI->SetPixelShaderConstantFast(pData->dwRegister, pData + 1, pData->dwCount);
  1096. }
  1097. break;
  1098. }
  1099. #ifdef DBG
  1100. default:
  1101. DXGASSERT(FALSE);
  1102. #endif
  1103. }
  1104. }
  1105. pDevI->m_dwRuntimeFlags &= ~D3DRT_EXECUTESTATEMODE;
  1106. }
  1107. catch(HRESULT ret)
  1108. {
  1109. pDevI->m_dwRuntimeFlags &= ~D3DRT_EXECUTESTATEMODE;
  1110. m_dwStateSetFlags &= ~__STATESET_HASONLYVERTEXSTATE;
  1111. throw ret;
  1112. }
  1113. }
  1114. //---------------------------------------------------------------------
  1115. #undef DPF_MODNAME
  1116. #define DPF_MODNAME "CStateSet::Capture"
  1117. void CStateSet::Capture(CD3DBase *pBaseDev, BOOL bFrontEndBuffer)
  1118. {
  1119. DWORD *p;
  1120. DWORD dwSize;
  1121. DWORD *pEnd;
  1122. // The device is not pure, so we can cast
  1123. DXGASSERT((pBaseDev->BehaviorFlags() & D3DCREATE_PUREDEVICE) == 0);
  1124. CD3DHal *pDevI = static_cast<CD3DHal*>(pBaseDev);
  1125. D3DFE_PROCESSVERTICES* pv = pDevI->m_pv;
  1126. // Texture coordinate indices must be restored before capturing, because
  1127. // we do not call GetTextureStageState but access tsstates directly
  1128. if (pv->dwDeviceFlags & D3DDEV_REMAPTEXTUREINDICES)
  1129. {
  1130. RestoreTextureStages(pDevI);
  1131. pDevI->ForceFVFRecompute();
  1132. }
  1133. if (bFrontEndBuffer)
  1134. {
  1135. p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
  1136. dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
  1137. }
  1138. else
  1139. {
  1140. p = (DWORD*)m_DriverBuffer.m_pBuffer;
  1141. dwSize = m_DriverBuffer.m_dwCurrentSize;
  1142. }
  1143. pEnd = (DWORD*)((BYTE*)p + dwSize);
  1144. while (p < pEnd)
  1145. {
  1146. LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
  1147. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  1148. switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
  1149. {
  1150. case D3DDP2OP_RENDERSTATE:
  1151. {
  1152. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1153. {
  1154. const D3DRENDERSTATETYPE state = (D3DRENDERSTATETYPE)*p++;
  1155. *p++ = pDevI->rstates[state];
  1156. }
  1157. break;
  1158. }
  1159. case D3DDP2OP_SETLIGHT:
  1160. {
  1161. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1162. {
  1163. LPD3DHAL_DP2SETLIGHT pData = (LPD3DHAL_DP2SETLIGHT)p;
  1164. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETLIGHT));
  1165. LPDIRECT3DLIGHTI pLight =
  1166. static_cast<DIRECT3DLIGHTI *>
  1167. ((*pDevI->m_pLightArray)[pData->dwIndex].m_pObj);
  1168. if(pData->dwIndex >= pDevI->m_pLightArray->GetSize())
  1169. {
  1170. D3D_ERR("Unable to capture light state (light not set?)");
  1171. throw D3DERR_INVALIDCALL;
  1172. }
  1173. switch (pData->dwDataType)
  1174. {
  1175. case D3DHAL_SETLIGHT_ENABLE:
  1176. if(!pLight->Enabled())
  1177. pData->dwDataType = D3DHAL_SETLIGHT_DISABLE;
  1178. break;
  1179. case D3DHAL_SETLIGHT_DISABLE:
  1180. if(pLight->Enabled())
  1181. pData->dwDataType = D3DHAL_SETLIGHT_ENABLE;
  1182. break;
  1183. case D3DHAL_SETLIGHT_DATA:
  1184. *((D3DLIGHT8*)p) = pLight->m_Light;
  1185. p = (LPDWORD)((LPBYTE)p + sizeof(D3DLIGHT8));
  1186. break;
  1187. }
  1188. }
  1189. break;
  1190. }
  1191. case D3DDP2OP_SETMATERIAL:
  1192. {
  1193. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1194. {
  1195. LPD3DHAL_DP2SETMATERIAL pData = (LPD3DHAL_DP2SETMATERIAL)p;
  1196. *pData = *((LPD3DHAL_DP2SETMATERIAL)&pv->lighting.material);
  1197. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETMATERIAL));
  1198. }
  1199. break;
  1200. }
  1201. case D3DDP2OP_SETTRANSFORM:
  1202. {
  1203. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1204. {
  1205. LPD3DHAL_DP2SETTRANSFORM pData = (LPD3DHAL_DP2SETTRANSFORM)p;
  1206. DWORD state = pData->xfrmType;
  1207. if ((DWORD)state >= __WORLDMATRIXBASE &&
  1208. (DWORD)state < __WORLDMATRIXBASE + __MAXWORLDMATRICES)
  1209. {
  1210. UINT index = (DWORD)state - __WORLDMATRIXBASE;
  1211. pData->matrix = *((LPD3DMATRIX)&pv->world[index]);
  1212. }
  1213. else
  1214. switch(pData->xfrmType)
  1215. {
  1216. case D3DTRANSFORMSTATE_VIEW:
  1217. pData->matrix = *((LPD3DMATRIX)&pv->view);
  1218. break;
  1219. case D3DTRANSFORMSTATE_PROJECTION:
  1220. pData->matrix = *((LPD3DMATRIX)&pDevI->transform.proj);
  1221. break;
  1222. case D3DTRANSFORMSTATE_TEXTURE0:
  1223. pData->matrix = *((LPD3DMATRIX)&pv->mTexture[0]);
  1224. break;
  1225. case D3DTRANSFORMSTATE_TEXTURE1:
  1226. pData->matrix = *((LPD3DMATRIX)&pv->mTexture[1]);
  1227. break;
  1228. case D3DTRANSFORMSTATE_TEXTURE2:
  1229. pData->matrix = *((LPD3DMATRIX)&pv->mTexture[2]);
  1230. break;
  1231. case D3DTRANSFORMSTATE_TEXTURE3:
  1232. pData->matrix = *((LPD3DMATRIX)&pv->mTexture[3]);
  1233. break;
  1234. case D3DTRANSFORMSTATE_TEXTURE4:
  1235. pData->matrix = *((LPD3DMATRIX)&pv->mTexture[4]);
  1236. break;
  1237. case D3DTRANSFORMSTATE_TEXTURE5:
  1238. pData->matrix = *((LPD3DMATRIX)&pv->mTexture[5]);
  1239. break;
  1240. case D3DTRANSFORMSTATE_TEXTURE6:
  1241. pData->matrix = *((LPD3DMATRIX)&pv->mTexture[6]);
  1242. break;
  1243. case D3DTRANSFORMSTATE_TEXTURE7:
  1244. pData->matrix = *((LPD3DMATRIX)&pv->mTexture[7]);
  1245. break;
  1246. }
  1247. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETTRANSFORM));
  1248. }
  1249. break;
  1250. }
  1251. case D3DDP2OP_TEXTURESTAGESTATE:
  1252. {
  1253. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1254. {
  1255. LPD3DHAL_DP2TEXTURESTAGESTATE pData = (LPD3DHAL_DP2TEXTURESTAGESTATE)p;
  1256. pData->dwValue = pDevI->tsstates[pData->wStage][pData->TSState];
  1257. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2TEXTURESTAGESTATE));
  1258. }
  1259. break;
  1260. }
  1261. case D3DDP2OP_FRONTENDDATA:
  1262. {
  1263. CBaseTexture* pTexOld = NULL;
  1264. CBaseTexture* pTexNew = NULL;
  1265. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1266. {
  1267. LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
  1268. pTexOld = CBaseTexture::SafeCast(pData->pTexture);
  1269. if( pTexOld )
  1270. pTexOld->DecrementUseCount();
  1271. pTexNew = pDevI->m_lpD3DMappedTexI[pData->wStage];
  1272. if( pTexNew )
  1273. pTexNew->IncrementUseCount();
  1274. if (pDevI->m_lpD3DMappedTexI[pData->wStage] != 0)
  1275. {
  1276. switch(pDevI->m_lpD3DMappedTexI[pData->wStage]->GetBufferDesc()->Type)
  1277. {
  1278. case D3DRTYPE_TEXTURE:
  1279. pData->pTexture = static_cast<IDirect3DTexture8*>(static_cast<CMipMap*>(pTexNew));
  1280. break;
  1281. case D3DRTYPE_CUBETEXTURE:
  1282. pData->pTexture = static_cast<IDirect3DCubeTexture8*>(static_cast<CCubeMap*>(pTexNew));
  1283. break;
  1284. case D3DRTYPE_VOLUMETEXTURE:
  1285. pData->pTexture = static_cast<IDirect3DVolumeTexture8*>(static_cast<CMipVolume*>(pTexNew));
  1286. break;
  1287. }
  1288. }
  1289. else
  1290. {
  1291. pData->pTexture = 0;
  1292. }
  1293. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
  1294. }
  1295. break;
  1296. }
  1297. case D3DDP2OP_FESETVB:
  1298. {
  1299. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1300. {
  1301. LPD3DHAL_DP2FESETVB pData = (LPD3DHAL_DP2FESETVB)p;
  1302. if( pData->pBuf )
  1303. pData->pBuf->DecrementUseCount();
  1304. pData->pBuf = pDevI->m_pStream[pData->wStream].m_pVB;
  1305. if( pData->pBuf )
  1306. pData->pBuf->IncrementUseCount();
  1307. pData->dwStride = pDevI->m_pStream[pData->wStream].m_dwStride;
  1308. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETVB));
  1309. }
  1310. break;
  1311. }
  1312. case D3DDP2OP_FESETIB:
  1313. {
  1314. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1315. {
  1316. LPD3DHAL_DP2FESETIB pData = (LPD3DHAL_DP2FESETIB)p;
  1317. if( pData->pBuf )
  1318. pData->pBuf->DecrementUseCount();
  1319. pData->pBuf = pDevI->m_pIndexStream->m_pVBI;
  1320. if( pData->pBuf )
  1321. pData->pBuf->IncrementUseCount();
  1322. pData->dwBase = pDevI->m_pIndexStream->m_dwBaseIndex;
  1323. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETIB));
  1324. }
  1325. break;
  1326. }
  1327. case D3DDP2OP_FESETPAL:
  1328. {
  1329. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1330. {
  1331. LPD3DHAL_DP2FESETPAL pData = (LPD3DHAL_DP2FESETPAL)p;
  1332. pData->dwPaletteNumber = pDevI->m_dwPalette;
  1333. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETPAL));
  1334. }
  1335. break;
  1336. }
  1337. case D3DDP2OP_VIEWPORTINFO:
  1338. {
  1339. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1340. {
  1341. D3DVIEWPORT8 viewport;
  1342. LPD3DHAL_DP2VIEWPORTINFO lpVwpData = (LPD3DHAL_DP2VIEWPORTINFO)p;
  1343. lpVwpData->dwX = pDevI->m_Viewport.X;
  1344. lpVwpData->dwY = pDevI->m_Viewport.Y;
  1345. lpVwpData->dwWidth = pDevI->m_Viewport.Width;
  1346. lpVwpData->dwHeight = pDevI->m_Viewport.Height;
  1347. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VIEWPORTINFO));
  1348. // The next command has to be D3DDP2OP_ZRANGE
  1349. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  1350. LPD3DHAL_DP2ZRANGE pData = (LPD3DHAL_DP2ZRANGE)p;
  1351. pData->dvMinZ = pDevI->m_Viewport.MinZ;
  1352. pData->dvMaxZ = pDevI->m_Viewport.MaxZ;
  1353. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2ZRANGE));
  1354. }
  1355. break;
  1356. }
  1357. case D3DDP2OP_SETCLIPPLANE:
  1358. {
  1359. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1360. {
  1361. LPD3DHAL_DP2SETCLIPPLANE pData = (LPD3DHAL_DP2SETCLIPPLANE)p;
  1362. *((LPD3DVECTORH)pData->plane) = pDevI->transform.userClipPlane[pData->dwIndex];
  1363. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETCLIPPLANE));
  1364. }
  1365. break;
  1366. }
  1367. case D3DDP2OP_SETVERTEXSHADER:
  1368. {
  1369. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1370. {
  1371. LPD3DHAL_DP2VERTEXSHADER pData = (LPD3DHAL_DP2VERTEXSHADER)p;
  1372. pData->dwHandle = pDevI->m_dwCurrentShaderHandle;
  1373. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2VERTEXSHADER));
  1374. }
  1375. break;
  1376. }
  1377. case D3DDP2OP_SETPIXELSHADER:
  1378. {
  1379. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1380. {
  1381. LPD3DHAL_DP2PIXELSHADER pData = (LPD3DHAL_DP2PIXELSHADER)p;
  1382. pData->dwHandle = pDevI->m_dwCurrentPixelShaderHandle;
  1383. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2PIXELSHADER));
  1384. }
  1385. break;
  1386. }
  1387. case D3DDP2OP_SETVERTEXSHADERCONST:
  1388. {
  1389. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1390. {
  1391. LPD3DHAL_DP2SETVERTEXSHADERCONST pData = (LPD3DHAL_DP2SETVERTEXSHADERCONST)p;
  1392. pDevI->m_pv->pGeometryFuncs->GetShaderConstants(pData->dwRegister, pData->dwCount, pData + 1);
  1393. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETVERTEXSHADERCONST) + pData->dwCount * 16);
  1394. }
  1395. break;
  1396. }
  1397. case D3DDP2OP_SETPIXELSHADERCONST:
  1398. {
  1399. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1400. {
  1401. LPD3DHAL_DP2SETPIXELSHADERCONST pData = (LPD3DHAL_DP2SETPIXELSHADERCONST)p;
  1402. pDevI->GetPixelShaderConstantI(pData->dwRegister,
  1403. pData->dwCount,
  1404. pData + 1);
  1405. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2SETPIXELSHADERCONST) + pData->dwCount * 16);
  1406. }
  1407. break;
  1408. }
  1409. #ifdef DBG
  1410. default:
  1411. DXGASSERT(FALSE);
  1412. #endif
  1413. }
  1414. }
  1415. }
  1416. //---------------------------------------------------------------------
  1417. #undef DPF_MODNAME
  1418. #define DPF_MODNAME "CStateSet::CreatePredefined"
  1419. void CStateSet::CreatePredefined(CD3DBase *pBaseDev, D3DSTATEBLOCKTYPE sbt)
  1420. {
  1421. static D3DRENDERSTATETYPE ALLrstates[] =
  1422. {
  1423. D3DRENDERSTATE_SPECULARENABLE,
  1424. D3DRENDERSTATE_ZENABLE,
  1425. D3DRENDERSTATE_FILLMODE,
  1426. D3DRENDERSTATE_SHADEMODE,
  1427. D3DRENDERSTATE_LINEPATTERN,
  1428. D3DRENDERSTATE_ZWRITEENABLE,
  1429. D3DRENDERSTATE_ALPHATESTENABLE,
  1430. D3DRENDERSTATE_LASTPIXEL,
  1431. D3DRENDERSTATE_SRCBLEND,
  1432. D3DRENDERSTATE_DESTBLEND,
  1433. D3DRENDERSTATE_CULLMODE,
  1434. D3DRENDERSTATE_ZFUNC,
  1435. D3DRENDERSTATE_ALPHAREF,
  1436. D3DRENDERSTATE_ALPHAFUNC,
  1437. D3DRENDERSTATE_DITHERENABLE,
  1438. D3DRENDERSTATE_FOGENABLE,
  1439. D3DRENDERSTATE_STIPPLEDALPHA,
  1440. D3DRENDERSTATE_FOGCOLOR,
  1441. D3DRENDERSTATE_FOGTABLEMODE,
  1442. D3DRENDERSTATE_FOGSTART,
  1443. D3DRENDERSTATE_FOGEND,
  1444. D3DRENDERSTATE_FOGDENSITY,
  1445. D3DRENDERSTATE_EDGEANTIALIAS,
  1446. D3DRENDERSTATE_ALPHABLENDENABLE,
  1447. D3DRENDERSTATE_ZBIAS,
  1448. D3DRENDERSTATE_RANGEFOGENABLE,
  1449. D3DRENDERSTATE_STENCILENABLE,
  1450. D3DRENDERSTATE_STENCILFAIL,
  1451. D3DRENDERSTATE_STENCILZFAIL,
  1452. D3DRENDERSTATE_STENCILPASS,
  1453. D3DRENDERSTATE_STENCILFUNC,
  1454. D3DRENDERSTATE_STENCILREF,
  1455. D3DRENDERSTATE_STENCILMASK,
  1456. D3DRENDERSTATE_STENCILWRITEMASK,
  1457. D3DRENDERSTATE_TEXTUREFACTOR,
  1458. D3DRENDERSTATE_WRAP0,
  1459. D3DRENDERSTATE_WRAP1,
  1460. D3DRENDERSTATE_WRAP2,
  1461. D3DRENDERSTATE_WRAP3,
  1462. D3DRENDERSTATE_WRAP4,
  1463. D3DRENDERSTATE_WRAP5,
  1464. D3DRENDERSTATE_WRAP6,
  1465. D3DRENDERSTATE_WRAP7,
  1466. D3DRENDERSTATE_AMBIENT,
  1467. D3DRENDERSTATE_COLORVERTEX,
  1468. D3DRENDERSTATE_FOGVERTEXMODE,
  1469. D3DRENDERSTATE_CLIPPING,
  1470. D3DRENDERSTATE_LIGHTING,
  1471. D3DRENDERSTATE_NORMALIZENORMALS,
  1472. D3DRENDERSTATE_LOCALVIEWER,
  1473. D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,
  1474. D3DRENDERSTATE_AMBIENTMATERIALSOURCE,
  1475. D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,
  1476. D3DRENDERSTATE_SPECULARMATERIALSOURCE,
  1477. D3DRENDERSTATE_VERTEXBLEND,
  1478. D3DRENDERSTATE_CLIPPLANEENABLE,
  1479. D3DRS_SOFTWAREVERTEXPROCESSING,
  1480. D3DRS_POINTSIZE,
  1481. D3DRS_POINTSIZE_MIN,
  1482. D3DRS_POINTSPRITEENABLE,
  1483. D3DRS_POINTSCALEENABLE,
  1484. D3DRS_POINTSCALE_A,
  1485. D3DRS_POINTSCALE_B,
  1486. D3DRS_POINTSCALE_C,
  1487. D3DRS_MULTISAMPLEANTIALIAS,
  1488. D3DRS_MULTISAMPLEMASK,
  1489. D3DRS_PATCHEDGESTYLE,
  1490. D3DRS_PATCHSEGMENTS,
  1491. D3DRS_POINTSIZE_MAX,
  1492. D3DRS_INDEXEDVERTEXBLENDENABLE,
  1493. D3DRS_COLORWRITEENABLE,
  1494. D3DRS_TWEENFACTOR,
  1495. D3DRS_BLENDOP,
  1496. D3DRS_POSITIONORDER,
  1497. D3DRS_NORMALORDER,
  1498. };
  1499. static D3DTEXTURESTAGESTATETYPE ALLtsstates[] =
  1500. {
  1501. D3DTSS_COLOROP,
  1502. D3DTSS_COLORARG1,
  1503. D3DTSS_COLORARG2,
  1504. D3DTSS_ALPHAOP,
  1505. D3DTSS_ALPHAARG1,
  1506. D3DTSS_ALPHAARG2,
  1507. D3DTSS_BUMPENVMAT00,
  1508. D3DTSS_BUMPENVMAT01,
  1509. D3DTSS_BUMPENVMAT10,
  1510. D3DTSS_BUMPENVMAT11,
  1511. D3DTSS_TEXCOORDINDEX,
  1512. D3DTSS_ADDRESSU,
  1513. D3DTSS_ADDRESSV,
  1514. D3DTSS_BORDERCOLOR,
  1515. D3DTSS_MAGFILTER,
  1516. D3DTSS_MINFILTER,
  1517. D3DTSS_MIPFILTER,
  1518. D3DTSS_MIPMAPLODBIAS,
  1519. D3DTSS_MAXMIPLEVEL,
  1520. D3DTSS_MAXANISOTROPY,
  1521. D3DTSS_BUMPENVLSCALE,
  1522. D3DTSS_BUMPENVLOFFSET,
  1523. D3DTSS_TEXTURETRANSFORMFLAGS,
  1524. D3DTSS_ADDRESSW,
  1525. D3DTSS_COLORARG0,
  1526. D3DTSS_ALPHAARG0,
  1527. D3DTSS_RESULTARG,
  1528. };
  1529. static D3DRENDERSTATETYPE PIXELrstates[] =
  1530. {
  1531. D3DRENDERSTATE_ZENABLE,
  1532. D3DRENDERSTATE_FILLMODE,
  1533. D3DRENDERSTATE_SHADEMODE,
  1534. D3DRENDERSTATE_LINEPATTERN,
  1535. D3DRENDERSTATE_ZWRITEENABLE,
  1536. D3DRENDERSTATE_ALPHATESTENABLE,
  1537. D3DRENDERSTATE_LASTPIXEL,
  1538. D3DRENDERSTATE_SRCBLEND,
  1539. D3DRENDERSTATE_DESTBLEND,
  1540. D3DRENDERSTATE_ZFUNC,
  1541. D3DRENDERSTATE_ALPHAREF,
  1542. D3DRENDERSTATE_ALPHAFUNC,
  1543. D3DRENDERSTATE_DITHERENABLE,
  1544. D3DRENDERSTATE_STIPPLEDALPHA,
  1545. D3DRENDERSTATE_FOGSTART,
  1546. D3DRENDERSTATE_FOGEND,
  1547. D3DRENDERSTATE_FOGDENSITY,
  1548. D3DRENDERSTATE_EDGEANTIALIAS,
  1549. D3DRENDERSTATE_ALPHABLENDENABLE,
  1550. D3DRENDERSTATE_ZBIAS,
  1551. D3DRENDERSTATE_STENCILENABLE,
  1552. D3DRENDERSTATE_STENCILFAIL,
  1553. D3DRENDERSTATE_STENCILZFAIL,
  1554. D3DRENDERSTATE_STENCILPASS,
  1555. D3DRENDERSTATE_STENCILFUNC,
  1556. D3DRENDERSTATE_STENCILREF,
  1557. D3DRENDERSTATE_STENCILMASK,
  1558. D3DRENDERSTATE_STENCILWRITEMASK,
  1559. D3DRENDERSTATE_TEXTUREFACTOR,
  1560. D3DRENDERSTATE_WRAP0,
  1561. D3DRENDERSTATE_WRAP1,
  1562. D3DRENDERSTATE_WRAP2,
  1563. D3DRENDERSTATE_WRAP3,
  1564. D3DRENDERSTATE_WRAP4,
  1565. D3DRENDERSTATE_WRAP5,
  1566. D3DRENDERSTATE_WRAP6,
  1567. D3DRENDERSTATE_WRAP7,
  1568. D3DRS_COLORWRITEENABLE,
  1569. D3DRS_BLENDOP,
  1570. };
  1571. static D3DTEXTURESTAGESTATETYPE PIXELtsstates[] =
  1572. {
  1573. D3DTSS_COLOROP,
  1574. D3DTSS_COLORARG1,
  1575. D3DTSS_COLORARG2,
  1576. D3DTSS_ALPHAOP,
  1577. D3DTSS_ALPHAARG1,
  1578. D3DTSS_ALPHAARG2,
  1579. D3DTSS_BUMPENVMAT00,
  1580. D3DTSS_BUMPENVMAT01,
  1581. D3DTSS_BUMPENVMAT10,
  1582. D3DTSS_BUMPENVMAT11,
  1583. D3DTSS_TEXCOORDINDEX,
  1584. D3DTSS_ADDRESSU,
  1585. D3DTSS_ADDRESSV,
  1586. D3DTSS_BORDERCOLOR,
  1587. D3DTSS_MAGFILTER,
  1588. D3DTSS_MINFILTER,
  1589. D3DTSS_MIPFILTER,
  1590. D3DTSS_MIPMAPLODBIAS,
  1591. D3DTSS_MAXMIPLEVEL,
  1592. D3DTSS_MAXANISOTROPY,
  1593. D3DTSS_BUMPENVLSCALE,
  1594. D3DTSS_BUMPENVLOFFSET,
  1595. D3DTSS_TEXTURETRANSFORMFLAGS,
  1596. D3DTSS_ADDRESSW,
  1597. D3DTSS_COLORARG0,
  1598. D3DTSS_ALPHAARG0,
  1599. D3DTSS_RESULTARG,
  1600. };
  1601. static D3DRENDERSTATETYPE VERTEXrstates[] =
  1602. {
  1603. D3DRENDERSTATE_SHADEMODE,
  1604. D3DRENDERSTATE_SPECULARENABLE,
  1605. D3DRENDERSTATE_CULLMODE,
  1606. D3DRENDERSTATE_FOGENABLE,
  1607. D3DRENDERSTATE_FOGCOLOR,
  1608. D3DRENDERSTATE_FOGTABLEMODE,
  1609. D3DRENDERSTATE_FOGSTART,
  1610. D3DRENDERSTATE_FOGEND,
  1611. D3DRENDERSTATE_FOGDENSITY,
  1612. D3DRENDERSTATE_RANGEFOGENABLE,
  1613. D3DRENDERSTATE_AMBIENT,
  1614. D3DRENDERSTATE_COLORVERTEX,
  1615. D3DRENDERSTATE_FOGVERTEXMODE,
  1616. D3DRENDERSTATE_CLIPPING,
  1617. D3DRENDERSTATE_LIGHTING,
  1618. D3DRENDERSTATE_NORMALIZENORMALS,
  1619. D3DRENDERSTATE_LOCALVIEWER,
  1620. D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,
  1621. D3DRENDERSTATE_AMBIENTMATERIALSOURCE,
  1622. D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,
  1623. D3DRENDERSTATE_SPECULARMATERIALSOURCE,
  1624. D3DRENDERSTATE_VERTEXBLEND,
  1625. D3DRENDERSTATE_CLIPPLANEENABLE,
  1626. D3DRS_SOFTWAREVERTEXPROCESSING,
  1627. D3DRS_POINTSIZE,
  1628. D3DRS_POINTSIZE_MIN,
  1629. D3DRS_POINTSPRITEENABLE,
  1630. D3DRS_POINTSCALEENABLE,
  1631. D3DRS_POINTSCALE_A,
  1632. D3DRS_POINTSCALE_B,
  1633. D3DRS_POINTSCALE_C,
  1634. D3DRS_MULTISAMPLEANTIALIAS,
  1635. D3DRS_MULTISAMPLEMASK,
  1636. D3DRS_PATCHEDGESTYLE,
  1637. D3DRS_PATCHSEGMENTS,
  1638. D3DRS_POINTSIZE_MAX,
  1639. D3DRS_INDEXEDVERTEXBLENDENABLE,
  1640. D3DRS_TWEENFACTOR,
  1641. D3DRS_POSITIONORDER,
  1642. D3DRS_NORMALORDER,
  1643. };
  1644. static D3DTEXTURESTAGESTATETYPE VERTEXtsstates[] =
  1645. {
  1646. D3DTSS_TEXCOORDINDEX,
  1647. D3DTSS_TEXTURETRANSFORMFLAGS
  1648. };
  1649. DWORD i;
  1650. BOOL bCapturePixelShaderState = TRUE;
  1651. // The device is not pure, so we can cast
  1652. DXGASSERT((pBaseDev->BehaviorFlags() & D3DCREATE_PUREDEVICE) == 0);
  1653. CD3DHal *pDevI = static_cast<CD3DHal*>(pBaseDev);
  1654. D3DFE_PROCESSVERTICES* pv = pDevI->m_pv;
  1655. // Texture coordinate indices must be restored before capturing, because
  1656. // we do not call GetTextureStageState but access tsstates directly
  1657. if (pv->dwDeviceFlags & D3DDEV_REMAPTEXTUREINDICES)
  1658. {
  1659. RestoreTextureStages(pDevI);
  1660. pDevI->ForceFVFRecompute();
  1661. }
  1662. switch(sbt)
  1663. {
  1664. case (D3DSTATEBLOCKTYPE)0:
  1665. break;
  1666. case D3DSBT_ALL:
  1667. for(i = 0; i < sizeof(ALLrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
  1668. pDevI->m_pStateSets->InsertRenderState(ALLrstates[i], pDevI->rstates[ALLrstates[i]], pDevI->CanHandleRenderState(ALLrstates[i]));
  1669. for (i = 0; i < pDevI->m_dwMaxTextureBlendStages; i++)
  1670. for(DWORD j = 0; j < sizeof(ALLtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
  1671. pDevI->m_pStateSets->InsertTextureStageState(i, ALLtsstates[j], pDevI->tsstates[i][ALLtsstates[j]]);
  1672. // Capture textures
  1673. for (i = 0; i < pDevI->m_dwMaxTextureBlendStages; i++)
  1674. {
  1675. IDirect3DBaseTexture8 *pTex;
  1676. if (pDevI->m_lpD3DMappedTexI[i] != 0)
  1677. {
  1678. switch(pDevI->m_lpD3DMappedTexI[i]->GetBufferDesc()->Type)
  1679. {
  1680. case D3DRTYPE_TEXTURE:
  1681. pTex = static_cast<IDirect3DTexture8*>(static_cast<CMipMap*>(pDevI->m_lpD3DMappedTexI[i]));
  1682. break;
  1683. case D3DRTYPE_CUBETEXTURE:
  1684. pTex = static_cast<IDirect3DCubeTexture8*>(static_cast<CCubeMap*>(pDevI->m_lpD3DMappedTexI[i]));
  1685. break;
  1686. case D3DRTYPE_VOLUMETEXTURE:
  1687. pTex = static_cast<IDirect3DVolumeTexture8*>(static_cast<CMipVolume*>(pDevI->m_lpD3DMappedTexI[i]));
  1688. break;
  1689. }
  1690. }
  1691. else
  1692. {
  1693. pTex = 0;
  1694. }
  1695. pDevI->m_pStateSets->InsertTexture(i, pTex);
  1696. }
  1697. // Capture current palette
  1698. pDevI->m_pStateSets->InsertCurrentTexturePalette(pDevI->m_dwPalette);
  1699. // Capture streams
  1700. for (i = 0; i < pDevI->m_dwNumStreams; i++)
  1701. {
  1702. pDevI->m_pStateSets->InsertStreamSource(i, pDevI->m_pStream[i].m_pVB, pDevI->m_pStream[i].m_dwStride);
  1703. }
  1704. pDevI->m_pStateSets->InsertIndices(pDevI->m_pIndexStream->m_pVBI, pDevI->m_pIndexStream->m_dwBaseIndex);
  1705. // Capture current viewport
  1706. pDevI->m_pStateSets->InsertViewport(&pDevI->m_Viewport);
  1707. // Capture current transforms
  1708. for (i = 0; i < __MAXWORLDMATRICES; i++)
  1709. {
  1710. pDevI->m_pStateSets->InsertTransform(D3DTS_WORLDMATRIX(i), (LPD3DMATRIX)&pv->world[i]);
  1711. }
  1712. pDevI->m_pStateSets->InsertTransform(D3DTRANSFORMSTATE_VIEW, (LPD3DMATRIX)&pv->view);
  1713. pDevI->m_pStateSets->InsertTransform(D3DTRANSFORMSTATE_PROJECTION, (LPD3DMATRIX)&pDevI->transform.proj);
  1714. for (i = 0; i < pDevI->m_dwMaxTextureBlendStages; i++)
  1715. {
  1716. pDevI->m_pStateSets->InsertTransform((D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0 + i), (LPD3DMATRIX)&pv->mTexture[i]);
  1717. }
  1718. // Capture current clip-planes
  1719. for (i = 0; i < pDevI->m_dwMaxUserClipPlanes; i++)
  1720. {
  1721. pDevI->m_pStateSets->InsertClipPlane(i, (LPD3DVALUE)&pDevI->transform.userClipPlane[i]);
  1722. }
  1723. // Capture current material
  1724. pDevI->m_pStateSets->InsertMaterial(&pv->lighting.material);
  1725. // Capture current lights
  1726. for (i = 0; i < pDevI->m_pLightArray->GetSize(); i++)
  1727. {
  1728. LPDIRECT3DLIGHTI pLight =
  1729. static_cast<DIRECT3DLIGHTI *>((*pDevI->m_pLightArray)[i].m_pObj);
  1730. if( pLight)
  1731. {
  1732. pDevI->m_pStateSets->InsertLight(i, &pLight->m_Light);
  1733. if(pLight->Enabled())
  1734. {
  1735. pDevI->m_pStateSets->InsertLightEnable(i, TRUE);
  1736. }
  1737. else
  1738. {
  1739. pDevI->m_pStateSets->InsertLightEnable(i, FALSE);
  1740. }
  1741. }
  1742. }
  1743. // Capture current shaders
  1744. if (D3DVSD_ISLEGACY(pDevI->m_dwCurrentShaderHandle))
  1745. {
  1746. pDevI->m_pStateSets->InsertVertexShader(pDevI->m_dwCurrentShaderHandle, TRUE);
  1747. }
  1748. else
  1749. {
  1750. CVShader* pShader = (CVShader*)pDevI->m_pVShaderArray->GetObject(pDevI->m_dwCurrentShaderHandle);
  1751. if (pShader->m_dwFlags & CVShader::SOFTWARE)
  1752. {
  1753. pDevI->m_pStateSets->InsertVertexShader(pDevI->m_dwCurrentShaderHandle, FALSE);
  1754. }
  1755. else
  1756. {
  1757. pDevI->m_pStateSets->InsertVertexShader(pDevI->m_dwCurrentShaderHandle, TRUE);
  1758. }
  1759. }
  1760. if( bCapturePixelShaderState )
  1761. pDevI->m_pStateSets->InsertPixelShader(pDevI->m_dwCurrentPixelShaderHandle);
  1762. // Capture shader constants. Use Microsoft's constants as a temp buffer
  1763. {
  1764. const UINT count = pDevI->m_MaxVertexShaderConst;
  1765. pDevI->GetVertexShaderConstant(0, pDevI->GeometryFuncsGuaranteed->m_VertexVM.GetRegisters()->m_c, count);
  1766. pDevI->m_pStateSets->InsertVertexShaderConstant(0, pDevI->GeometryFuncsGuaranteed->m_VertexVM.GetRegisters()->m_c, count);
  1767. }
  1768. // Capture pixel shader constants
  1769. if( bCapturePixelShaderState )
  1770. {
  1771. // Note this is hardcoded to 8. ff.ff supports 16 but here we capture only 8.
  1772. pDevI->m_pStateSets->InsertPixelShaderConstant(0, pDevI->m_PShaderConstReg, 8 );
  1773. }
  1774. break;
  1775. case D3DSBT_PIXELSTATE:
  1776. for(i = 0; i < sizeof(PIXELrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
  1777. pDevI->m_pStateSets->InsertRenderState(PIXELrstates[i], pDevI->rstates[PIXELrstates[i]], pDevI->CanHandleRenderState(PIXELrstates[i]));
  1778. for (i = 0; i < pDevI->m_dwMaxTextureBlendStages; i++)
  1779. for(DWORD j = 0; j < sizeof(PIXELtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
  1780. pDevI->m_pStateSets->InsertTextureStageState(i, PIXELtsstates[j], pDevI->tsstates[i][PIXELtsstates[j]]);
  1781. // Capture pixel shader constants
  1782. if( bCapturePixelShaderState )
  1783. pDevI->m_pStateSets->InsertPixelShaderConstant(0, pDevI->m_PShaderConstReg,
  1784. D3DPS_CONSTREG_MAX_DX8);
  1785. // Capture current pixel shader
  1786. if( bCapturePixelShaderState )
  1787. pDevI->m_pStateSets->InsertPixelShader(pDevI->m_dwCurrentPixelShaderHandle);
  1788. break;
  1789. case D3DSBT_VERTEXSTATE:
  1790. for(i = 0; i < sizeof(VERTEXrstates) / sizeof(D3DRENDERSTATETYPE); ++i)
  1791. pDevI->m_pStateSets->InsertRenderState(VERTEXrstates[i], pDevI->rstates[VERTEXrstates[i]], pDevI->CanHandleRenderState(VERTEXrstates[i]));
  1792. for (i = 0; i < pDevI->m_dwMaxTextureBlendStages; i++)
  1793. for(DWORD j = 0; j < sizeof(VERTEXtsstates) / sizeof(D3DTEXTURESTAGESTATETYPE); ++j)
  1794. pDevI->m_pStateSets->InsertTextureStageState(i, VERTEXtsstates[j], pDevI->tsstates[i][VERTEXtsstates[j]]);
  1795. // Capture current light enables
  1796. for (i = 0; i < pDevI->m_pLightArray->GetSize(); i++)
  1797. {
  1798. LPDIRECT3DLIGHTI pLight =
  1799. static_cast<DIRECT3DLIGHTI *>((*pDevI->m_pLightArray)[i].m_pObj);
  1800. if( pLight)
  1801. {
  1802. pDevI->m_pStateSets->InsertLight(i, &pLight->m_Light);
  1803. if(pLight->Enabled())
  1804. {
  1805. pDevI->m_pStateSets->InsertLightEnable(i, TRUE);
  1806. }
  1807. else
  1808. {
  1809. pDevI->m_pStateSets->InsertLightEnable(i, FALSE);
  1810. }
  1811. }
  1812. }
  1813. // Capture shader constants. Use Microsoft's constants as a temp buffer
  1814. {
  1815. const UINT count = pDevI->m_MaxVertexShaderConst;
  1816. pDevI->GetVertexShaderConstant(0, pDevI->GeometryFuncsGuaranteed->m_VertexVM.GetRegisters()->m_c, count);
  1817. pDevI->m_pStateSets->InsertVertexShaderConstant(0, pDevI->GeometryFuncsGuaranteed->m_VertexVM.GetRegisters()->m_c, count);
  1818. }
  1819. // Capture current vertex shader
  1820. if (D3DVSD_ISLEGACY(pDevI->m_dwCurrentShaderHandle))
  1821. {
  1822. pDevI->m_pStateSets->InsertVertexShader(pDevI->m_dwCurrentShaderHandle, TRUE);
  1823. }
  1824. else
  1825. {
  1826. CVShader* pShader = (CVShader*)pDevI->m_pVShaderArray->GetObject(pDevI->m_dwCurrentShaderHandle);
  1827. if (pShader->m_dwFlags & CVShader::SOFTWARE)
  1828. {
  1829. pDevI->m_pStateSets->InsertVertexShader(pDevI->m_dwCurrentShaderHandle, FALSE);
  1830. }
  1831. else
  1832. {
  1833. pDevI->m_pStateSets->InsertVertexShader(pDevI->m_dwCurrentShaderHandle, TRUE);
  1834. }
  1835. }
  1836. break;
  1837. default:
  1838. throw D3DERR_INVALIDCALL;
  1839. }
  1840. pDevI->m_pStateSets->EndSet();
  1841. pDevI->m_pDDI->WriteStateSetToDevice(sbt);
  1842. }
  1843. //---------------------------------------------------------------------
  1844. #undef DPF_MODNAME
  1845. #define DPF_MODNAME "CPureStateSet::InsertCommand"
  1846. void CPureStateSet::InsertCommand(D3DHAL_DP2OPERATION op, LPVOID pData,
  1847. DWORD dwDataSize,
  1848. BOOL bDriverCanHandle)
  1849. {
  1850. switch(op)
  1851. {
  1852. case D3DDP2OP_FRONTENDDATA:
  1853. case D3DDP2OP_FESETVB:
  1854. case D3DDP2OP_FESETIB:
  1855. m_FEOnlyBuffer.InsertCommand(op, pData, dwDataSize);
  1856. break;
  1857. default:
  1858. m_DriverBuffer.InsertCommand(op, pData, dwDataSize);
  1859. }
  1860. }
  1861. //---------------------------------------------------------------------
  1862. #undef DPF_MODNAME
  1863. #define DPF_MODNAME "CPureStateSet::Execute"
  1864. void CPureStateSet::Execute(CD3DBase *pDevI, BOOL bFrontEndBuffer)
  1865. {
  1866. DWORD *p;
  1867. DWORD dwSize;
  1868. DWORD *pEnd;
  1869. if (bFrontEndBuffer)
  1870. {
  1871. p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
  1872. dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
  1873. }
  1874. else
  1875. {
  1876. return;
  1877. }
  1878. pEnd = (DWORD*)((BYTE*)p + dwSize);
  1879. while (p < pEnd)
  1880. {
  1881. LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
  1882. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  1883. switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
  1884. {
  1885. case D3DDP2OP_FRONTENDDATA:
  1886. {
  1887. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1888. {
  1889. LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
  1890. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
  1891. HRESULT ret = pDevI->SetTexture(pData->wStage, pData->pTexture);
  1892. if (ret != D3D_OK)
  1893. throw ret;
  1894. }
  1895. break;
  1896. }
  1897. case D3DDP2OP_FESETVB:
  1898. {
  1899. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1900. {
  1901. LPD3DHAL_DP2FESETVB pData = (LPD3DHAL_DP2FESETVB)p;
  1902. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETVB));
  1903. HRESULT ret = pDevI->SetStreamSource(pData->wStream, pData->pBuf, pData->dwStride);
  1904. if (ret != D3D_OK)
  1905. throw ret;
  1906. }
  1907. break;
  1908. }
  1909. case D3DDP2OP_FESETIB:
  1910. {
  1911. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1912. {
  1913. LPD3DHAL_DP2FESETIB pData = (LPD3DHAL_DP2FESETIB)p;
  1914. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETIB));
  1915. HRESULT ret = pDevI->SetIndices(pData->pBuf, pData->dwBase);
  1916. if (ret != D3D_OK)
  1917. throw ret;
  1918. }
  1919. break;
  1920. }
  1921. case D3DDP2OP_FESETPAL:
  1922. {
  1923. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1924. {
  1925. LPD3DHAL_DP2FESETPAL pData = (LPD3DHAL_DP2FESETPAL)p;
  1926. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETPAL));
  1927. if( pData->dwPaletteNumber != __INVALIDPALETTE )
  1928. {
  1929. HRESULT ret = pDevI->SetCurrentTexturePalette(pData->dwPaletteNumber);
  1930. if (ret != D3D_OK)
  1931. throw ret;
  1932. }
  1933. }
  1934. break;
  1935. }
  1936. #ifdef DBG
  1937. default:
  1938. DXGASSERT(FALSE);
  1939. #endif
  1940. }
  1941. }
  1942. }
  1943. //---------------------------------------------------------------------
  1944. #undef DPF_MODNAME
  1945. #define DPF_MODNAME "CPureStateSet::Capture"
  1946. void CPureStateSet::Capture(CD3DBase *pDevI, BOOL bFrontEndBuffer)
  1947. {
  1948. DWORD *p;
  1949. DWORD dwSize;
  1950. DWORD *pEnd;
  1951. if (bFrontEndBuffer)
  1952. {
  1953. p = (DWORD*)m_FEOnlyBuffer.m_pBuffer;
  1954. dwSize = m_FEOnlyBuffer.m_dwCurrentSize;
  1955. }
  1956. else
  1957. {
  1958. return;
  1959. }
  1960. pEnd = (DWORD*)((BYTE*)p + dwSize);
  1961. while (p < pEnd)
  1962. {
  1963. LPD3DHAL_DP2COMMAND pCommand = (LPD3DHAL_DP2COMMAND)p;
  1964. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2COMMAND));
  1965. switch ((D3DHAL_DP2OPERATION)pCommand->bCommand)
  1966. {
  1967. case D3DDP2OP_FRONTENDDATA:
  1968. {
  1969. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  1970. {
  1971. LPD3DHAL_DP2FRONTENDDATA pData = (LPD3DHAL_DP2FRONTENDDATA)p;
  1972. CBaseTexture* pTexOld = NULL;
  1973. CBaseTexture* pTexNew = NULL;
  1974. pTexOld = CBaseTexture::SafeCast(pData->pTexture);
  1975. if( pTexOld )
  1976. pTexOld->DecrementUseCount();
  1977. pTexNew = pDevI->m_lpD3DMappedTexI[pData->wStage];
  1978. if( pTexNew )
  1979. pTexNew->IncrementUseCount();
  1980. if (pDevI->m_lpD3DMappedTexI[pData->wStage] != 0)
  1981. {
  1982. switch(pDevI->m_lpD3DMappedTexI[pData->wStage]->GetBufferDesc()->Type)
  1983. {
  1984. case D3DRTYPE_TEXTURE:
  1985. pData->pTexture = static_cast<IDirect3DTexture8*>(static_cast<CMipMap*>(pTexNew));
  1986. break;
  1987. case D3DRTYPE_CUBETEXTURE:
  1988. pData->pTexture = static_cast<IDirect3DCubeTexture8*>(static_cast<CCubeMap*>(pTexNew));
  1989. break;
  1990. case D3DRTYPE_VOLUMETEXTURE:
  1991. pData->pTexture = static_cast<IDirect3DVolumeTexture8*>(static_cast<CMipVolume*>(pTexNew));
  1992. break;
  1993. }
  1994. }
  1995. else
  1996. {
  1997. pData->pTexture = 0;
  1998. }
  1999. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FRONTENDDATA));
  2000. }
  2001. break;
  2002. }
  2003. case D3DDP2OP_FESETVB:
  2004. {
  2005. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  2006. {
  2007. LPD3DHAL_DP2FESETVB pData = (LPD3DHAL_DP2FESETVB)p;
  2008. if( pData->pBuf )
  2009. {
  2010. pData->pBuf->DecrementUseCount();
  2011. }
  2012. pData->pBuf = pDevI->m_pStream[pData->wStream].m_pVB;
  2013. if( pData->pBuf )
  2014. {
  2015. pData->pBuf->IncrementUseCount();
  2016. }
  2017. pData->dwStride = pDevI->m_pStream[pData->wStream].m_dwStride;
  2018. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETVB));
  2019. }
  2020. break;
  2021. }
  2022. case D3DDP2OP_FESETIB:
  2023. {
  2024. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  2025. {
  2026. LPD3DHAL_DP2FESETIB pData = (LPD3DHAL_DP2FESETIB)p;
  2027. pData->pBuf = pDevI->m_pIndexStream->m_pVBI;
  2028. if( pData->pBuf )
  2029. {
  2030. pData->pBuf->DecrementUseCount();
  2031. }
  2032. pData->dwBase = pDevI->m_pIndexStream->m_dwBaseIndex;
  2033. if( pData->pBuf )
  2034. {
  2035. pData->pBuf->IncrementUseCount();
  2036. }
  2037. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETIB));
  2038. }
  2039. break;
  2040. }
  2041. case D3DDP2OP_FESETPAL:
  2042. {
  2043. for(DWORD i = 0; i < (DWORD)pCommand->wStateCount; ++i)
  2044. {
  2045. LPD3DHAL_DP2FESETPAL pData = (LPD3DHAL_DP2FESETPAL)p;
  2046. pData->dwPaletteNumber = pDevI->m_dwPalette;
  2047. p = (DWORD*)((BYTE*)p + sizeof(D3DHAL_DP2FESETPAL));
  2048. }
  2049. break;
  2050. }
  2051. #ifdef DBG
  2052. default:
  2053. DXGASSERT(FALSE);
  2054. #endif
  2055. }
  2056. }
  2057. }
  2058. //---------------------------------------------------------------------
  2059. #undef DPF_MODNAME
  2060. #define DPF_MODNAME "CPureStateSet::CreatePredefined"
  2061. void CPureStateSet::CreatePredefined(CD3DBase *pDevI, D3DSTATEBLOCKTYPE sbt)
  2062. {
  2063. DWORD i;
  2064. // The device is not pure, so we can cast
  2065. switch(sbt)
  2066. {
  2067. case (D3DSTATEBLOCKTYPE)0:
  2068. break;
  2069. case D3DSBT_ALL:
  2070. // Capture textures
  2071. for (i = 0; i < pDevI->m_dwMaxTextureBlendStages; i++)
  2072. {
  2073. IDirect3DBaseTexture8 *pTex;
  2074. if (pDevI->m_lpD3DMappedTexI[i] != 0)
  2075. {
  2076. switch(pDevI->m_lpD3DMappedTexI[i]->GetBufferDesc()->Type)
  2077. {
  2078. case D3DRTYPE_TEXTURE:
  2079. pTex = static_cast<IDirect3DTexture8*>(static_cast<CMipMap*>(pDevI->m_lpD3DMappedTexI[i]));
  2080. break;
  2081. case D3DRTYPE_CUBETEXTURE:
  2082. pTex = static_cast<IDirect3DCubeTexture8*>(static_cast<CCubeMap*>(pDevI->m_lpD3DMappedTexI[i]));
  2083. break;
  2084. case D3DRTYPE_VOLUMETEXTURE:
  2085. pTex = static_cast<IDirect3DVolumeTexture8*>(static_cast<CMipVolume*>(pDevI->m_lpD3DMappedTexI[i]));
  2086. break;
  2087. }
  2088. }
  2089. else
  2090. {
  2091. pTex = 0;
  2092. }
  2093. pDevI->m_pStateSets->InsertTexture(i, pTex);
  2094. }
  2095. // Capture streams
  2096. for (i = 0; i < pDevI->m_dwNumStreams; i++)
  2097. {
  2098. pDevI->m_pStateSets->InsertStreamSource(i, pDevI->m_pStream[i].m_pVB, pDevI->m_pStream[i].m_dwStride);
  2099. }
  2100. pDevI->m_pStateSets->InsertIndices(pDevI->m_pIndexStream->m_pVBI, pDevI->m_pIndexStream->m_dwBaseIndex);
  2101. break;
  2102. case D3DSBT_PIXELSTATE:
  2103. break;
  2104. case D3DSBT_VERTEXSTATE:
  2105. break;
  2106. default:
  2107. throw D3DERR_INVALIDCALL;
  2108. }
  2109. pDevI->m_pStateSets->EndSet();
  2110. DWORD DeviceHandle;
  2111. pDevI->m_pStateSets->CreateNewDeviceHandle(&DeviceHandle);
  2112. pDevI->m_pDDI->InsertStateSetOp(D3DHAL_STATESETCREATE, DeviceHandle, sbt);
  2113. }
  2114. //=====================================================================
  2115. // CStateSetBuffer interface
  2116. //
  2117. #undef DPF_MODNAME
  2118. #define DPF_MODNAME "CStateSetBuffer::InsertCommand"
  2119. void CStateSetBuffer::InsertCommand(D3DHAL_DP2OPERATION op, LPVOID pData, DWORD dwDataSize)
  2120. {
  2121. const DWORD GROWSIZE = 1024;
  2122. if (m_pDP2CurrCommand != 0 && m_pDP2CurrCommand->bCommand == op)
  2123. {
  2124. if (dwDataSize + m_dwCurrentSize <= m_dwBufferSize)
  2125. {
  2126. ++m_pDP2CurrCommand->wStateCount;
  2127. memcpy(m_pBuffer + m_dwCurrentSize, pData, dwDataSize);
  2128. m_dwCurrentSize += dwDataSize;
  2129. return;
  2130. }
  2131. }
  2132. // Check for space
  2133. if (sizeof(D3DHAL_DP2COMMAND) + dwDataSize + m_dwCurrentSize > m_dwBufferSize)
  2134. {
  2135. // We need to grow the buffer
  2136. DWORD dwNewBufferSize = max(m_dwBufferSize + GROWSIZE, sizeof(D3DHAL_DP2COMMAND) + dwDataSize + m_dwCurrentSize);
  2137. BYTE *pTmp = new BYTE[dwNewBufferSize];
  2138. if (pTmp == NULL)
  2139. {
  2140. D3D_ERR("Not enough memory to create state block buffer");
  2141. throw E_OUTOFMEMORY;
  2142. }
  2143. if (m_pBuffer)
  2144. {
  2145. memcpy(pTmp, m_pBuffer, m_dwCurrentSize);
  2146. delete [] m_pBuffer;
  2147. }
  2148. m_pBuffer = pTmp;
  2149. m_dwBufferSize = dwNewBufferSize;
  2150. }
  2151. // Add new instruction
  2152. m_pDP2CurrCommand = (LPD3DHAL_DP2COMMAND)(m_pBuffer + m_dwCurrentSize);
  2153. m_pDP2CurrCommand->bCommand = op;
  2154. m_pDP2CurrCommand->bReserved = 0;
  2155. m_pDP2CurrCommand->wStateCount = 1;
  2156. m_dwCurrentSize += sizeof(D3DHAL_DP2COMMAND);
  2157. memcpy(m_pBuffer + m_dwCurrentSize, pData, dwDataSize);
  2158. m_dwCurrentSize += dwDataSize;
  2159. return;
  2160. }