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.

2526 lines
90 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3dstate.c
  8. *
  9. * Contains code to translate D3D renderstates and texture stage
  10. * states into hardware specific settings.
  11. *
  12. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  13. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  14. \*****************************************************************************/
  15. #include "precomp.h"
  16. #include "d3dhw.h"
  17. #include "d3dcntxt.h"
  18. #include "d3ddelta.h"
  19. #include "d3dtxman.h"
  20. #define ALLOC_TAG ALLOC_TAG_SD2P
  21. //-----------------------------------------------------------------------------
  22. //
  23. // void __SelectFVFTexCoord
  24. //
  25. // This utility function sets the correct texture offset depending on the
  26. // texturing coordinate set wished to be used from the FVF vertexes
  27. //
  28. //-----------------------------------------------------------------------------
  29. void
  30. __SelectFVFTexCoord(LPP2FVFOFFSETS lpP2FVFOff, DWORD dwTexCoord)
  31. {
  32. DBG_D3D((10,"Entering __SelectFVFTexCoord"));
  33. lpP2FVFOff->dwTexOffset = lpP2FVFOff->dwTexBaseOffset +
  34. dwTexCoord * 2 * sizeof(D3DVALUE);
  35. // verify the requested texture coordinate doesn't exceed the FVF
  36. // vertex structure provided , if so go down to set 0 as a
  37. // crash-avoiding alternative
  38. if (lpP2FVFOff->dwTexOffset >= lpP2FVFOff->dwStride)
  39. lpP2FVFOff->dwTexOffset = lpP2FVFOff->dwTexBaseOffset;
  40. DBG_D3D((10,"Exiting __SelectFVFTexCoord"));
  41. } // __SelectFVFTexCoord
  42. //-----------------------------------------------------------------------------
  43. //
  44. // HRESULT __HWPreProcessTSS
  45. //
  46. // Processes the state changes that must be done as soon as they arrive
  47. //
  48. //-----------------------------------------------------------------------------
  49. void __HWPreProcessTSS(PERMEDIA_D3DCONTEXT *pContext,
  50. DWORD dwStage,
  51. DWORD dwState,
  52. DWORD dwValue)
  53. {
  54. DBG_D3D((10,"Entering __HWPreProcessTSS"));
  55. if (D3DTSS_ADDRESS == dwState)
  56. {
  57. pContext->TssStates[D3DTSS_ADDRESSU] = dwValue;
  58. pContext->TssStates[D3DTSS_ADDRESSV] = dwValue;
  59. }
  60. else
  61. if (D3DTSS_TEXTUREMAP == dwState && 0 != dwValue)
  62. {
  63. PPERMEDIA_D3DTEXTURE pTexture=TextureHandleToPtr(dwValue, pContext);
  64. if (CHECK_D3DSURFACE_VALIDITY(pTexture) &&
  65. (pTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE))
  66. {
  67. TextureCacheManagerIncNumTexturesSet(pContext->pTextureManager);
  68. if (pTexture->m_dwHeapIndex)
  69. TextureCacheManagerIncNumSetTexInVid(pContext->pTextureManager);
  70. }
  71. }
  72. DBG_D3D((10,"Exiting __HWPreProcessTSS"));
  73. } // __HWPreProcessTSS
  74. //-----------------------------------------------------------------------------
  75. //
  76. // HRESULT __HWSetupStageStates
  77. //
  78. // Processes the state changes related to the DX6 texture stage states in the
  79. // current rendering context
  80. //
  81. //-----------------------------------------------------------------------------
  82. HRESULT WINAPI __HWSetupStageStates(PERMEDIA_D3DCONTEXT *pContext,
  83. LPP2FVFOFFSETS lpP2FVFOff)
  84. {
  85. __P2RegsSoftwareCopy* pSoftPermedia = &pContext->Hdr.SoftCopyP2Regs;
  86. DWORD *pFlags = &pContext->Hdr.Flags;
  87. PERMEDIA_DEFS(pContext->ppdev);
  88. DBG_D3D((10,"Entering __HWSetupStageStates"));
  89. // If we are to texture map our primitives
  90. if (pContext->TssStates[D3DTSS_TEXTUREMAP])
  91. {
  92. DWORD dwMag = pContext->TssStates[D3DTSS_MAGFILTER];
  93. DWORD dwMin = pContext->TssStates[D3DTSS_MINFILTER];
  94. DWORD dwMip = pContext->TssStates[D3DTSS_MIPFILTER];
  95. DWORD dwCop = pContext->TssStates[D3DTSS_COLOROP];
  96. DWORD dwCa1 = pContext->TssStates[D3DTSS_COLORARG1];
  97. DWORD dwCa2 = pContext->TssStates[D3DTSS_COLORARG2];
  98. DWORD dwAop = pContext->TssStates[D3DTSS_ALPHAOP];
  99. DWORD dwAa1 = pContext->TssStates[D3DTSS_ALPHAARG1];
  100. DWORD dwAa2 = pContext->TssStates[D3DTSS_ALPHAARG2];
  101. DWORD dwTau = pContext->TssStates[D3DTSS_ADDRESSU];
  102. DWORD dwTav = pContext->TssStates[D3DTSS_ADDRESSV];
  103. DWORD dwTxc = pContext->TssStates[D3DTSS_TEXCOORDINDEX];
  104. DBG_D3D((6,"Setting up w TSS:"
  105. "dwCop=%x dwCa1=%x dwCa2=%x dwAop=%x dwAa1=%x dwAa2=%x "
  106. "dwMag=%x dwMin=%x dwMip=%x dwTau=%x dwTav=%x dwTxc=%x",
  107. dwCop, dwCa1, dwCa2, dwAop, dwAa1, dwAa2,
  108. dwMag, dwMin, dwMip, dwTau, dwTav, dwTxc));
  109. // Choose texture coord to use
  110. __SelectFVFTexCoord( lpP2FVFOff, dwTxc);
  111. // Current is the same as diffuse in stage 0
  112. if (dwCa2 == D3DTA_CURRENT)
  113. dwCa2 = D3DTA_DIFFUSE;
  114. if (dwAa2 == D3DTA_CURRENT)
  115. dwAa2 = D3DTA_DIFFUSE;
  116. // Check if we need to disable texturing
  117. if (dwCop == D3DTOP_DISABLE ||
  118. (dwCop == D3DTOP_SELECTARG2 && dwCa2 == D3DTA_DIFFUSE &&
  119. dwAop == D3DTOP_SELECTARG2 && dwAa2 == D3DTA_DIFFUSE))
  120. {
  121. //Please don't clear pContext->TssStates[D3DTSS_TEXTUREMAP] though
  122. pContext->CurrentTextureHandle = 0;
  123. DBG_D3D((10,"Exiting __HWSetupStageStates , texturing disabled"));
  124. return DD_OK;
  125. }
  126. // setup the address mode
  127. switch (dwTau) {
  128. case D3DTADDRESS_CLAMP:
  129. pSoftPermedia->TextureReadMode.SWrapMode = _P2_TEXTURE_CLAMP;
  130. break;
  131. case D3DTADDRESS_WRAP:
  132. pSoftPermedia->TextureReadMode.SWrapMode = _P2_TEXTURE_REPEAT;
  133. break;
  134. case D3DTADDRESS_MIRROR:
  135. pSoftPermedia->TextureReadMode.SWrapMode = _P2_TEXTURE_MIRROR;
  136. break;
  137. default:
  138. DBG_D3D((2, "Illegal value passed to TSS U address mode = %d"
  139. ,dwTau));
  140. pSoftPermedia->TextureReadMode.SWrapMode = _P2_TEXTURE_REPEAT;
  141. break;
  142. }
  143. switch (dwTav) {
  144. case D3DTADDRESS_CLAMP:
  145. pSoftPermedia->TextureReadMode.TWrapMode = _P2_TEXTURE_CLAMP;
  146. break;
  147. case D3DTADDRESS_WRAP:
  148. pSoftPermedia->TextureReadMode.TWrapMode = _P2_TEXTURE_REPEAT;
  149. break;
  150. case D3DTADDRESS_MIRROR:
  151. pSoftPermedia->TextureReadMode.TWrapMode = _P2_TEXTURE_MIRROR;
  152. break;
  153. default:
  154. DBG_D3D((2, "Illegal value passed to TSS V address mode = %d"
  155. ,dwTav));
  156. pSoftPermedia->TextureReadMode.TWrapMode = _P2_TEXTURE_REPEAT;
  157. break;
  158. }
  159. RESERVEDMAPTR(1);
  160. COPY_PERMEDIA_DATA(TextureReadMode, pSoftPermedia->TextureReadMode);
  161. COMMITDMAPTR();
  162. // Enable-disable wrapping flags for U & V
  163. if (pContext->dwWrap[dwTxc] & D3DWRAPCOORD_0)
  164. {
  165. *pFlags |= CTXT_HAS_WRAPU_ENABLED;
  166. }
  167. else
  168. {
  169. *pFlags &= ~CTXT_HAS_WRAPU_ENABLED;
  170. }
  171. if (pContext->dwWrap[dwTxc] & D3DWRAPCOORD_1)
  172. {
  173. *pFlags |= CTXT_HAS_WRAPV_ENABLED;
  174. }
  175. else
  176. {
  177. *pFlags &= ~CTXT_HAS_WRAPV_ENABLED;
  178. }
  179. // Setup the equivalent texture filtering state
  180. if (dwMip == D3DTFP_NONE)
  181. {
  182. // We can only take care of magnification filtering on the P2
  183. if (dwMag == D3DTFG_LINEAR)
  184. {
  185. pContext->bMagFilter = TRUE; // D3DFILTER_LINEAR;
  186. }
  187. else if (dwMag == D3DTFG_POINT)
  188. {
  189. pContext->bMagFilter = FALSE; // D3DFILTER_NEAREST;
  190. }
  191. }
  192. else if (dwMip == D3DTFP_POINT)
  193. {
  194. if (dwMin == D3DTFN_POINT)
  195. {
  196. pContext->bMagFilter = FALSE; // D3DFILTER_MIPNEAREST;
  197. }
  198. else if (dwMin == D3DTFN_LINEAR)
  199. {
  200. pContext->bMagFilter = TRUE; // D3DFILTER_MIPLINEAR;
  201. }
  202. }
  203. else
  204. { // dwMip == D3DTFP_LINEAR
  205. if (dwMin == D3DTFN_POINT)
  206. {
  207. pContext->bMagFilter = TRUE; // D3DFILTER_LINEARMIPNEAREST;
  208. }
  209. else if (dwMin == D3DTFN_LINEAR)
  210. {
  211. pContext->bMagFilter = TRUE; // D3DFILTER_LINEARMIPLINEAR;
  212. }
  213. }
  214. // Setup the equivalent texture blending state
  215. // Check if we need to decal
  216. if ((dwCa1 == D3DTA_TEXTURE && dwCop == D3DTOP_SELECTARG1) &&
  217. (dwAa1 == D3DTA_TEXTURE && dwAop == D3DTOP_SELECTARG1))
  218. {
  219. // D3DTBLEND_COPY;
  220. pSoftPermedia->TextureColorMode.ApplicationMode =
  221. _P2_TEXTURE_COPY;
  222. }
  223. // check if we the app modified the TSS for decaling after first
  224. // setting it up for modulating via the legacy renderstates
  225. // this is a Permedia2 specific optimization.
  226. else if ((dwCa1 == D3DTA_TEXTURE && dwCop == D3DTOP_SELECTARG1) &&
  227. (dwAa1 == D3DTA_TEXTURE && dwAop == D3DTOP_LEGACY_ALPHAOVR))
  228. {
  229. // D3DTBLEND_COPY;
  230. pSoftPermedia->TextureColorMode.ApplicationMode =
  231. _P2_TEXTURE_COPY;
  232. }
  233. // Check if we need to modulate & pass texture alpha
  234. else if ((dwCa2 == D3DTA_DIFFUSE && dwCa1 == D3DTA_TEXTURE) &&
  235. dwCop == D3DTOP_MODULATE &&
  236. (dwAa1 == D3DTA_TEXTURE && dwAop == D3DTOP_SELECTARG1))
  237. {
  238. // D3DTBLEND_MODULATE;
  239. pSoftPermedia->TextureColorMode.ApplicationMode =
  240. _P2_TEXTURE_MODULATE;
  241. }
  242. // Check if we need to modulate & pass diffuse alpha
  243. else if ((dwCa2 == D3DTA_DIFFUSE && dwCa1 == D3DTA_TEXTURE) &&
  244. dwCop == D3DTOP_MODULATE &&
  245. (dwAa2 == D3DTA_DIFFUSE && dwAop == D3DTOP_SELECTARG2))
  246. {
  247. // D3DTBLEND_MODULATE;
  248. pSoftPermedia->TextureColorMode.ApplicationMode =
  249. _P2_TEXTURE_MODULATE;
  250. }
  251. // Check if we need to do legacy modulate
  252. else if ((dwCa2 == D3DTA_DIFFUSE && dwCa1 == D3DTA_TEXTURE) &&
  253. dwCop == D3DTOP_MODULATE &&
  254. (dwAa1 == D3DTA_TEXTURE && dwAop == D3DTOP_LEGACY_ALPHAOVR))
  255. {
  256. // D3DTBLEND_MODULATE;
  257. pSoftPermedia->TextureColorMode.ApplicationMode =
  258. _P2_TEXTURE_MODULATE;
  259. }
  260. // Check if we need to decal alpha
  261. else if ((dwCa2 == D3DTA_DIFFUSE && dwCa1 == D3DTA_TEXTURE) &&
  262. dwCop == D3DTOP_BLENDTEXTUREALPHA &&
  263. (dwAa2 == D3DTA_DIFFUSE && dwAop == D3DTOP_SELECTARG2))
  264. {
  265. // D3DTBLEND_DECALALPHA;
  266. pSoftPermedia->TextureColorMode.ApplicationMode =
  267. _P2_TEXTURE_DECAL;
  268. }
  269. // Check if we need to modulate alpha
  270. else if ((dwCa2 == D3DTA_DIFFUSE && dwCa1 == D3DTA_TEXTURE) &&
  271. dwCop == D3DTOP_MODULATE &&
  272. (dwAa2 == D3DTA_DIFFUSE && dwAa1 == D3DTA_TEXTURE) &&
  273. dwAop == D3DTOP_MODULATE)
  274. {
  275. // D3DTBLEND_MODULATEALPHA;
  276. pSoftPermedia->TextureColorMode.ApplicationMode =
  277. _P2_TEXTURE_MODULATE;
  278. } else
  279. {
  280. DBG_D3D((0,"Trying to setup a state we don't understand!"));
  281. }
  282. RESERVEDMAPTR(1);
  283. COPY_PERMEDIA_DATA(TextureColorMode, pSoftPermedia->TextureColorMode);
  284. COMMITDMAPTR();
  285. pContext->CurrentTextureHandle = pContext->TssStates[D3DTSS_TEXTUREMAP];
  286. }
  287. else
  288. // No texturing
  289. pContext->CurrentTextureHandle = 0;
  290. DIRTY_TEXTURE;
  291. DBG_D3D((10,"Exiting __HWSetupStageStates"));
  292. return DD_OK;
  293. } //__HWSetupStageStates
  294. //-----------------------------------------------------------------------------
  295. //
  296. // void __HandleDirtyPermediaState
  297. //
  298. // Setup of context that is deferred until just before
  299. // rendering an actual rendering primitive
  300. //
  301. //-----------------------------------------------------------------------------
  302. void
  303. __HandleDirtyPermediaState(PPDev ppdev,
  304. PERMEDIA_D3DCONTEXT* pContext,
  305. LPP2FVFOFFSETS lpP2FVFOff)
  306. {
  307. __P2RegsSoftwareCopy* pSoftPermedia = &pContext->Hdr.SoftCopyP2Regs;
  308. PERMEDIA_DEFS(pContext->ppdev);
  309. ULONG AlphaBlendSend;
  310. DBG_D3D((10,"Entering __HandleDirtyPermediaState"));
  311. // We need to keep this ordering of evaluation on the P2
  312. // --------------Have the texture or the stage states changed ? -----------
  313. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_TEXTURE)
  314. {
  315. DBG_D3D((4,"preparing to handle CONTEXT_DIRTY_TEXTURE"));
  316. // Choose between legacy Texture Handle or TSS
  317. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_MULTITEXTURE)
  318. {
  319. pContext->dwDirtyFlags &= ~CONTEXT_DIRTY_MULTITEXTURE;
  320. //Setup TSS state AND textures
  321. if ( SUCCEEDED(__HWSetupStageStates(pContext, lpP2FVFOff)) )
  322. {
  323. // if this FVF has no tex coordinates at all disable texturing
  324. if (lpP2FVFOff->dwTexBaseOffset == 0)
  325. {
  326. pContext->CurrentTextureHandle = 0;
  327. DBG_D3D((2,"No texture coords present in FVF "
  328. "to texture map primitives"));
  329. }
  330. }
  331. else
  332. {
  333. pContext->CurrentTextureHandle = 0;
  334. DBG_D3D((0,"TSS Setup failed"));
  335. }
  336. }
  337. else
  338. {
  339. // select default texture coordinate index
  340. __SelectFVFTexCoord( lpP2FVFOff, 0);
  341. }
  342. }
  343. // --------------Has the state of the LB changed ? ------------------------
  344. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_ZBUFFER)
  345. {
  346. DBG_D3D((4,"CONTEXT_DIRTY_ZBUFFER handled"));
  347. pContext->dwDirtyFlags &= ~CONTEXT_DIRTY_ZBUFFER;
  348. if ((pContext->Hdr.Flags & CTXT_HAS_ZBUFFER_ENABLED) &&
  349. (pContext->ZBufferHandle))
  350. {
  351. if (pContext->Hdr.Flags & CTXT_HAS_ZWRITE_ENABLED)
  352. {
  353. if (__PERMEDIA_DEPTH_COMPARE_MODE_NEVER ==
  354. (int)pSoftPermedia->DepthMode.CompareMode)
  355. {
  356. pSoftPermedia->LBReadMode.ReadDestinationEnable =
  357. __PERMEDIA_DISABLE;
  358. pSoftPermedia->LBWriteMode.WriteEnable = __PERMEDIA_DISABLE;
  359. }
  360. else
  361. {
  362. pSoftPermedia->LBReadMode.ReadDestinationEnable =
  363. __PERMEDIA_ENABLE;
  364. pSoftPermedia->LBWriteMode.WriteEnable = __PERMEDIA_ENABLE;
  365. }
  366. pSoftPermedia->DepthMode.WriteMask = __PERMEDIA_ENABLE;
  367. }
  368. else
  369. {
  370. pSoftPermedia->LBReadMode.ReadDestinationEnable =
  371. __PERMEDIA_ENABLE;
  372. pSoftPermedia->LBWriteMode.WriteEnable = __PERMEDIA_DISABLE;
  373. pSoftPermedia->DepthMode.WriteMask = __PERMEDIA_DISABLE;
  374. }
  375. // We are Z Buffering
  376. // Enable Z test
  377. pSoftPermedia->DepthMode.UnitEnable = __PERMEDIA_ENABLE;
  378. // Tell delta we are Z Buffering.
  379. pSoftPermedia->DeltaMode.DepthEnable = 1;
  380. }
  381. else
  382. {
  383. // We are NOT Z Buffering
  384. // Disable Writes
  385. pSoftPermedia->LBWriteMode.WriteEnable = __PERMEDIA_DISABLE;
  386. // Disable Z test
  387. pSoftPermedia->DepthMode.UnitEnable = __PERMEDIA_DISABLE;
  388. pSoftPermedia->DepthMode.WriteMask = __PERMEDIA_DISABLE;
  389. // No reads, no writes
  390. pSoftPermedia->LBReadMode.ReadDestinationEnable =
  391. __PERMEDIA_DISABLE;
  392. // Tell delta we aren't Z Buffering.
  393. pSoftPermedia->DeltaMode.DepthEnable = 0;
  394. }
  395. if (__PERMEDIA_ENABLE == pSoftPermedia->StencilMode.UnitEnable)
  396. {
  397. pSoftPermedia->LBReadMode.ReadDestinationEnable = __PERMEDIA_ENABLE;
  398. pSoftPermedia->LBWriteMode.WriteEnable = __PERMEDIA_ENABLE;
  399. }
  400. RESERVEDMAPTR(7);
  401. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  402. COPY_PERMEDIA_DATA(StencilMode, pSoftPermedia->StencilMode);
  403. COPY_PERMEDIA_DATA(StencilData, pSoftPermedia->StencilData);
  404. COPY_PERMEDIA_DATA(Window, pSoftPermedia->Window);
  405. COPY_PERMEDIA_DATA(DepthMode, pSoftPermedia->DepthMode);
  406. COPY_PERMEDIA_DATA(LBReadMode, pSoftPermedia->LBReadMode);
  407. COPY_PERMEDIA_DATA(LBWriteMode, pSoftPermedia->LBWriteMode);
  408. COMMITDMAPTR();
  409. } // if CONTEXT_DIRTY_ZBUFFER
  410. // ----------------Has the alphablend type changed ? ----------------------
  411. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_ALPHABLEND)
  412. {
  413. // Only clear when we have an alphablend dirty context
  414. pContext->FakeBlendNum &= ~FAKE_ALPHABLEND_ONE_ONE;
  415. pContext->dwDirtyFlags &= ~CONTEXT_DIRTY_ALPHABLEND;
  416. // Verify that requested blend mode is HW supported
  417. DWORD dwBlendMode;
  418. dwBlendMode =
  419. (((DWORD)pSoftPermedia->AlphaBlendMode.SourceBlend) |
  420. ((DWORD)pSoftPermedia->AlphaBlendMode.DestinationBlend) << 4);
  421. DBG_D3D((4,"CONTEXT_DIRTY_ALPHABLEND handled: Blend mode = %08lx",
  422. dwBlendMode));
  423. switch (dwBlendMode) {
  424. // In this case, we set the bit to the QuickDraw mode
  425. case __PERMEDIA_BLENDOP_ONE_AND_INVSRCALPHA:
  426. DBG_D3D((4,"Blend Operation is PreMult"));
  427. pSoftPermedia->AlphaBlendMode.BlendType = 1;
  428. break;
  429. // This is the standard blend
  430. case __PERMEDIA_BLENDOP_SRCALPHA_AND_INVSRCALPHA:
  431. DBG_D3D((4,"Blend Operation is Blend"));
  432. pSoftPermedia->AlphaBlendMode.BlendType = 0;
  433. break;
  434. case ((__PERMEDIA_BLEND_FUNC_ZERO << 4) |
  435. __PERMEDIA_BLEND_FUNC_SRC_ALPHA):
  436. // we substitute the SrcBlend = SrcAlpha DstBlend = 1
  437. // with the 1,0 mode since we really dont' support
  438. // it, just so apps perform reasonably
  439. pSoftPermedia->AlphaBlendMode.AlphaBlendEnable = 0;
  440. case ((__PERMEDIA_BLEND_FUNC_ONE << 4)
  441. | __PERMEDIA_BLEND_FUNC_ZERO):
  442. case __PERMEDIA_BLENDOP_ONE_AND_ZERO:
  443. // This is code for 'no blending'
  444. DBG_D3D((4,"Blend Operation is validly None"));
  445. break;
  446. case ((__PERMEDIA_BLEND_FUNC_ONE << 4) |
  447. __PERMEDIA_BLEND_FUNC_SRC_ALPHA):
  448. // we substitute the SrcBlend = SrcAlpha DstBlend = 1
  449. // with the 1,1 mode since we really dont' support
  450. // it, just so apps perform reasonably
  451. case __PERMEDIA_BLENDOP_ONE_AND_ONE:
  452. DBG_D3D((4,"BlendOperation is 1 Source, 1 Dest"));
  453. pSoftPermedia->AlphaBlendMode.BlendType = 1;
  454. pContext->FakeBlendNum |= FAKE_ALPHABLEND_ONE_ONE;
  455. break;
  456. default:
  457. DBG_D3D((2,"Blend Operation is invalid! BlendOp == %x",
  458. dwBlendMode));
  459. // This is a fallback blending mode
  460. dwBlendMode = __PERMEDIA_BLENDOP_ONE_AND_ZERO;
  461. break;
  462. }
  463. if ((pContext->Hdr.Flags & CTXT_HAS_ALPHABLEND_ENABLED) &&
  464. (dwBlendMode != __PERMEDIA_BLENDOP_ONE_AND_ZERO))
  465. {
  466. // Set the AlphaBlendMode register on Permedia
  467. pSoftPermedia->AlphaBlendMode.AlphaBlendEnable = 1;
  468. // Turn on destination read in the FBReadMode register
  469. pSoftPermedia->FBReadMode.ReadDestinationEnable = 1;
  470. }
  471. else
  472. {
  473. // Set the AlphaBlendMode register on Permedia
  474. pSoftPermedia->AlphaBlendMode.AlphaBlendEnable = 0;
  475. // Turn off the destination read in FbReadMode register
  476. pSoftPermedia->FBReadMode.ReadDestinationEnable = 0;
  477. // if not sending alpha, turn alpha to 1
  478. RESERVEDMAPTR(1);
  479. SEND_PERMEDIA_DATA(AStart, PM_BYTE_COLOR(0xFF));
  480. COMMITDMAPTR();
  481. }
  482. AlphaBlendSend = ((DWORD)*(DWORD*)(&pSoftPermedia->AlphaBlendMode));
  483. // Insert changes in blend mode for unsupported blend operations
  484. // in this function
  485. if (FAKE_ALPHABLEND_ONE_ONE & pContext->FakeBlendNum)
  486. {
  487. AlphaBlendSend &= 0xFFFFFF01;
  488. AlphaBlendSend |= (__PERMEDIA_BLENDOP_ONE_AND_INVSRCALPHA << 1);
  489. }
  490. RESERVEDMAPTR(2);
  491. COPY_PERMEDIA_DATA(FBReadMode, pSoftPermedia->FBReadMode);
  492. COPY_PERMEDIA_DATA(AlphaBlendMode, AlphaBlendSend);
  493. COMMITDMAPTR();
  494. }
  495. // --------------------Has the texture handle changed ? -------------------
  496. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_TEXTURE)
  497. {
  498. pContext->dwDirtyFlags &= ~CONTEXT_DIRTY_TEXTURE;
  499. DBG_D3D((4,"CONTEXT_DIRTY_TEXTURE handled"));
  500. if (pContext->CurrentTextureHandle == 0)
  501. DisableTexturePermedia(pContext);
  502. else
  503. EnableTexturePermedia(pContext);
  504. }
  505. DBG_D3D((10,"Exiting __HandleDirtyPermediaState"));
  506. } // __HandleDirtyPermediaState
  507. //-----------------------------------------------------------------------------
  508. //
  509. // void __MapRS_Into_TSS0
  510. //
  511. // Map Renderstate changes into the corresponding change in the Texture Stage
  512. // State #0 .
  513. //
  514. //-----------------------------------------------------------------------------
  515. void
  516. __MapRS_Into_TSS0(PERMEDIA_D3DCONTEXT* pContext,
  517. DWORD dwRSType,
  518. DWORD dwRSVal)
  519. {
  520. DBG_D3D((10,"Entering __MapRS_Into_TSS0"));
  521. // Process each specific renderstate
  522. switch (dwRSType)
  523. {
  524. case D3DRENDERSTATE_TEXTUREHANDLE:
  525. //Mirror texture related render states into TSS stage 0
  526. pContext->TssStates[D3DTSS_TEXTUREMAP] = dwRSVal;
  527. break;
  528. case D3DRENDERSTATE_TEXTUREMAPBLEND:
  529. switch (dwRSVal)
  530. {
  531. case D3DTBLEND_DECALALPHA:
  532. //Mirror texture related render states into TSS stage 0
  533. pContext->TssStates[D3DTSS_COLOROP] =
  534. D3DTOP_BLENDTEXTUREALPHA;
  535. pContext->TssStates[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  536. pContext->TssStates[D3DTSS_COLORARG2] = D3DTA_DIFFUSE;
  537. pContext->TssStates[D3DTSS_ALPHAOP] = D3DTOP_SELECTARG2;
  538. pContext->TssStates[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  539. pContext->TssStates[D3DTSS_ALPHAARG2] = D3DTA_DIFFUSE;
  540. break;
  541. case D3DTBLEND_MODULATE:
  542. //Mirror texture related render states into TSS stage 0
  543. pContext->TssStates[D3DTSS_COLOROP] = D3DTOP_MODULATE;
  544. pContext->TssStates[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  545. pContext->TssStates[D3DTSS_COLORARG2] = D3DTA_DIFFUSE;
  546. // a special legacy alpha operation is called for
  547. // that depends on the format of the texture
  548. pContext->TssStates[D3DTSS_ALPHAOP] = D3DTOP_LEGACY_ALPHAOVR;
  549. pContext->TssStates[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  550. pContext->TssStates[D3DTSS_ALPHAARG2] = D3DTA_DIFFUSE;
  551. break;
  552. case D3DTBLEND_MODULATEALPHA:
  553. //Mirror texture related render states into TSS stage 0
  554. pContext->TssStates[D3DTSS_COLOROP] = D3DTOP_MODULATE;
  555. pContext->TssStates[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  556. pContext->TssStates[D3DTSS_COLORARG2] = D3DTA_DIFFUSE;
  557. pContext->TssStates[D3DTSS_ALPHAOP] = D3DTOP_MODULATE;
  558. pContext->TssStates[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;;
  559. pContext->TssStates[D3DTSS_ALPHAARG2] = D3DTA_DIFFUSE;
  560. break;
  561. case D3DTBLEND_COPY:
  562. case D3DTBLEND_DECAL:
  563. //Mirror texture related render states into TSS stage 0
  564. pContext->TssStates[D3DTSS_COLOROP] = D3DTOP_SELECTARG1;
  565. pContext->TssStates[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  566. pContext->TssStates[D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1;
  567. pContext->TssStates[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  568. break;
  569. case D3DTBLEND_ADD:
  570. //Mirror texture related render states into TSS stage 0
  571. pContext->TssStates[D3DTSS_COLOROP] = D3DTOP_ADD;
  572. pContext->TssStates[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  573. pContext->TssStates[D3DTSS_COLORARG2] = D3DTA_DIFFUSE;
  574. pContext->TssStates[D3DTSS_ALPHAOP] = D3DTOP_SELECTARG2;
  575. pContext->TssStates[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  576. pContext->TssStates[D3DTSS_ALPHAARG2] = D3DTA_DIFFUSE;
  577. }
  578. break;
  579. case D3DRENDERSTATE_BORDERCOLOR:
  580. //Mirror texture related render states into TSS stage 0
  581. pContext->TssStates[D3DTSS_BORDERCOLOR] = dwRSVal;
  582. break;
  583. case D3DRENDERSTATE_MIPMAPLODBIAS:
  584. //Mirror texture related render states into TSS stage 0
  585. pContext->TssStates[D3DTSS_MIPMAPLODBIAS] = dwRSVal;
  586. break;
  587. case D3DRENDERSTATE_ANISOTROPY:
  588. //Mirror texture related render states into TSS stage 0
  589. pContext->TssStates[D3DTSS_MAXANISOTROPY] = dwRSVal;
  590. break;
  591. case D3DRENDERSTATE_TEXTUREADDRESS:
  592. //Mirror texture related render states into TSS stage 0
  593. pContext->TssStates[D3DTSS_ADDRESSU] =
  594. pContext->TssStates[D3DTSS_ADDRESSV] = dwRSVal;
  595. break;
  596. case D3DRENDERSTATE_TEXTUREADDRESSU:
  597. //Mirror texture related render states into TSS stage 0
  598. pContext->TssStates[D3DTSS_ADDRESSU] = dwRSVal;
  599. break;
  600. case D3DRENDERSTATE_TEXTUREADDRESSV:
  601. //Mirror texture related render states into TSS stage 0
  602. pContext->TssStates[D3DTSS_ADDRESSV] = dwRSVal;
  603. break;
  604. case D3DRENDERSTATE_TEXTUREMAG:
  605. switch(dwRSVal)
  606. {
  607. case D3DFILTER_NEAREST:
  608. pContext->TssStates[D3DTSS_MAGFILTER] = D3DTFG_POINT;
  609. break;
  610. case D3DFILTER_LINEAR:
  611. case D3DFILTER_MIPLINEAR:
  612. case D3DFILTER_MIPNEAREST:
  613. case D3DFILTER_LINEARMIPNEAREST:
  614. case D3DFILTER_LINEARMIPLINEAR:
  615. pContext->TssStates[D3DTSS_MAGFILTER] = D3DTFG_LINEAR;
  616. break;
  617. default:
  618. break;
  619. }
  620. break;
  621. case D3DRENDERSTATE_TEXTUREMIN:
  622. switch(dwRSVal)
  623. {
  624. case D3DFILTER_NEAREST:
  625. pContext->TssStates[D3DTSS_MINFILTER] = D3DTFN_POINT;
  626. pContext->TssStates[D3DTSS_MIPFILTER] = D3DTFP_NONE;
  627. break;
  628. case D3DFILTER_LINEAR:
  629. pContext->TssStates[D3DTSS_MINFILTER] = D3DTFN_LINEAR;
  630. pContext->TssStates[D3DTSS_MIPFILTER] = D3DTFP_NONE;
  631. break;
  632. case D3DFILTER_MIPNEAREST:
  633. pContext->TssStates[D3DTSS_MINFILTER] = D3DTFN_POINT;
  634. pContext->TssStates[D3DTSS_MIPFILTER] = D3DTFP_POINT;
  635. break;
  636. case D3DFILTER_MIPLINEAR:
  637. pContext->TssStates[D3DTSS_MINFILTER] = D3DTFN_LINEAR;
  638. pContext->TssStates[D3DTSS_MIPFILTER] = D3DTFP_POINT;
  639. break;
  640. case D3DFILTER_LINEARMIPNEAREST:
  641. pContext->TssStates[D3DTSS_MINFILTER] = D3DTFN_POINT;
  642. pContext->TssStates[D3DTSS_MIPFILTER] = D3DTFP_LINEAR;
  643. break;
  644. case D3DFILTER_LINEARMIPLINEAR:
  645. pContext->TssStates[D3DTSS_MINFILTER] = D3DTFN_LINEAR;
  646. pContext->TssStates[D3DTSS_MIPFILTER] = D3DTFP_LINEAR;
  647. break;;
  648. default:
  649. break;
  650. }
  651. break;
  652. default:
  653. // All other renderstates don't have a corresponding TSS state so
  654. // we don't have to worry about mapping them.
  655. break;
  656. } // switch (dwRSType of renderstate)
  657. DBG_D3D((10,"Exiting __MapRS_Into_TSS0"));
  658. } // __MapRS_Into_TSS0
  659. //-----------------------------------------------------------------------------
  660. //
  661. // void __ProcessRenderState
  662. //
  663. // Handle a single render state change
  664. //
  665. //-----------------------------------------------------------------------------
  666. void
  667. __ProcessRenderStates(PERMEDIA_D3DCONTEXT* pContext,
  668. DWORD dwRSType,
  669. DWORD dwRSVal)
  670. {
  671. __P2RegsSoftwareCopy* pSoftPermedia = &pContext->Hdr.SoftCopyP2Regs;
  672. DWORD* pFlags = &pContext->Hdr.Flags;
  673. PERMEDIA_DEFS(pContext->ppdev);
  674. DBG_D3D((10,"Entering __ProcessRenderStates"));
  675. // Process each specific renderstate
  676. switch (dwRSType) {
  677. case D3DRENDERSTATE_TEXTUREMAPBLEND:
  678. DBG_D3D((8, "ChangeState: Texture Blend Mode 0x%x "
  679. "(D3DTEXTUREBLEND)", dwRSVal));
  680. switch (dwRSVal) {
  681. case D3DTBLEND_DECALALPHA:
  682. pSoftPermedia->TextureColorMode.ApplicationMode =
  683. _P2_TEXTURE_DECAL;
  684. break;
  685. case D3DTBLEND_MODULATE:
  686. pSoftPermedia->TextureColorMode.ApplicationMode =
  687. _P2_TEXTURE_MODULATE;
  688. break;
  689. case D3DTBLEND_MODULATEALPHA:
  690. pSoftPermedia->TextureColorMode.ApplicationMode =
  691. _P2_TEXTURE_MODULATE;
  692. break;
  693. case D3DTBLEND_COPY:
  694. case D3DTBLEND_DECAL:
  695. pSoftPermedia->TextureColorMode.ApplicationMode =
  696. _P2_TEXTURE_COPY;
  697. break;
  698. }
  699. RESERVEDMAPTR(1);
  700. COPY_PERMEDIA_DATA(TextureColorMode,
  701. pSoftPermedia->TextureColorMode);
  702. COMMITDMAPTR();
  703. DIRTY_TEXTURE; // May need to change DDA
  704. break;
  705. case D3DRENDERSTATE_TEXTUREADDRESS:
  706. DBG_D3D((8, "ChangeState: Texture address 0x%x "
  707. "(D3DTEXTUREADDRESS)", dwRSVal));
  708. switch (dwRSVal) {
  709. case D3DTADDRESS_CLAMP:
  710. pSoftPermedia->TextureReadMode.TWrapMode =
  711. _P2_TEXTURE_CLAMP;
  712. pSoftPermedia->TextureReadMode.SWrapMode =
  713. _P2_TEXTURE_CLAMP;
  714. break;
  715. case D3DTADDRESS_WRAP:
  716. pSoftPermedia->TextureReadMode.TWrapMode =
  717. _P2_TEXTURE_REPEAT;
  718. pSoftPermedia->TextureReadMode.SWrapMode =
  719. _P2_TEXTURE_REPEAT;
  720. break;
  721. case D3DTADDRESS_MIRROR:
  722. pSoftPermedia->TextureReadMode.TWrapMode =
  723. _P2_TEXTURE_MIRROR;
  724. pSoftPermedia->TextureReadMode.SWrapMode =
  725. _P2_TEXTURE_MIRROR;
  726. break;
  727. default:
  728. DBG_D3D((2, "Illegal value passed to ChangeState "
  729. " D3DRENDERSTATE_TEXTUREADDRESS = %d",
  730. dwRSVal));
  731. // set a fallback value
  732. pSoftPermedia->TextureReadMode.TWrapMode =
  733. _P2_TEXTURE_REPEAT;
  734. pSoftPermedia->TextureReadMode.SWrapMode =
  735. _P2_TEXTURE_REPEAT;
  736. break;
  737. }
  738. RESERVEDMAPTR(1);
  739. COPY_PERMEDIA_DATA(TextureReadMode,
  740. pSoftPermedia->TextureReadMode);
  741. COMMITDMAPTR();
  742. break;
  743. case D3DRENDERSTATE_TEXTUREADDRESSU:
  744. DBG_D3D((8, "ChangeState: Texture address 0x%x "
  745. "(D3DTEXTUREADDRESSU)", dwRSVal));
  746. switch (dwRSVal) {
  747. case D3DTADDRESS_CLAMP:
  748. pSoftPermedia->TextureReadMode.SWrapMode =
  749. _P2_TEXTURE_CLAMP;
  750. break;
  751. case D3DTADDRESS_WRAP:
  752. pSoftPermedia->TextureReadMode.SWrapMode =
  753. _P2_TEXTURE_REPEAT;
  754. break;
  755. case D3DTADDRESS_MIRROR:
  756. pSoftPermedia->TextureReadMode.SWrapMode =
  757. _P2_TEXTURE_MIRROR;
  758. break;
  759. default:
  760. DBG_D3D((2, "Illegal value passed to ChangeState "
  761. " D3DRENDERSTATE_TEXTUREADDRESSU = %d",
  762. dwRSVal));
  763. // set a fallback value
  764. pSoftPermedia->TextureReadMode.SWrapMode =
  765. _P2_TEXTURE_REPEAT;
  766. break;
  767. }
  768. RESERVEDMAPTR(1);
  769. COPY_PERMEDIA_DATA(TextureReadMode, pSoftPermedia->TextureReadMode);
  770. COMMITDMAPTR();
  771. break;
  772. case D3DRENDERSTATE_TEXTUREADDRESSV:
  773. DBG_D3D((8, "ChangeState: Texture address 0x%x "
  774. "(D3DTEXTUREADDRESSV)", dwRSVal));
  775. switch (dwRSVal) {
  776. case D3DTADDRESS_CLAMP:
  777. pSoftPermedia->TextureReadMode.TWrapMode =
  778. _P2_TEXTURE_CLAMP;
  779. break;
  780. case D3DTADDRESS_WRAP:
  781. pSoftPermedia->TextureReadMode.TWrapMode =
  782. _P2_TEXTURE_REPEAT;
  783. break;
  784. case D3DTADDRESS_MIRROR:
  785. pSoftPermedia->TextureReadMode.TWrapMode =
  786. _P2_TEXTURE_MIRROR;
  787. break;
  788. default:
  789. DBG_D3D((2, "Illegal value passed to ChangeState "
  790. " D3DRENDERSTATE_TEXTUREADDRESSV = %d",
  791. dwRSVal));
  792. // set a fallback value
  793. pSoftPermedia->TextureReadMode.TWrapMode =
  794. _P2_TEXTURE_REPEAT;
  795. break;
  796. }
  797. RESERVEDMAPTR(1);
  798. COPY_PERMEDIA_DATA(TextureReadMode, pSoftPermedia->TextureReadMode);
  799. COMMITDMAPTR();
  800. break;
  801. case D3DRENDERSTATE_TEXTUREHANDLE:
  802. DBG_D3D((8, "ChangeState: Texture Handle 0x%x",dwRSVal));
  803. if (dwRSVal != pContext->CurrentTextureHandle)
  804. {
  805. pContext->CurrentTextureHandle = dwRSVal;
  806. DIRTY_TEXTURE;
  807. }
  808. break;
  809. case D3DRENDERSTATE_ANTIALIAS:
  810. DBG_D3D((8, "ChangeState: AntiAlias 0x%x",dwRSVal));
  811. NOT_HANDLED;
  812. break;
  813. case D3DRENDERSTATE_WRAPU:
  814. DBG_D3D((8, "ChangeState: Wrap_U "
  815. "(BOOL) 0x%x",dwRSVal));
  816. if (dwRSVal)
  817. {
  818. *pFlags |= CTXT_HAS_WRAPU_ENABLED;
  819. }
  820. else
  821. {
  822. *pFlags &= ~CTXT_HAS_WRAPU_ENABLED;
  823. }
  824. break;
  825. case D3DRENDERSTATE_WRAPV:
  826. DBG_D3D((8, "ChangeState: Wrap_V "
  827. "(BOOL) 0x%x",dwRSVal));
  828. if (dwRSVal)
  829. {
  830. *pFlags |= CTXT_HAS_WRAPV_ENABLED;
  831. }
  832. else
  833. {
  834. *pFlags &= ~CTXT_HAS_WRAPV_ENABLED;
  835. }
  836. break;
  837. case D3DRENDERSTATE_LINEPATTERN:
  838. DBG_D3D((8, "ChangeState: Line Pattern "
  839. "(D3DLINEPATTERN) 0x%x",dwRSVal));
  840. NOT_HANDLED;
  841. break;
  842. case D3DRENDERSTATE_ZWRITEENABLE:
  843. DBG_D3D((8, "ChangeState: Z Write Enable "
  844. "(BOOL) 0x%x",dwRSVal));
  845. if (dwRSVal != 0)
  846. {
  847. // Local Buffer Write mode
  848. if (!(*pFlags & CTXT_HAS_ZWRITE_ENABLED))
  849. {
  850. DBG_D3D((8, " Enabling Z Writes"));
  851. *pFlags |= CTXT_HAS_ZWRITE_ENABLED;
  852. DIRTY_ZBUFFER;
  853. }
  854. }
  855. else
  856. {
  857. if (*pFlags & CTXT_HAS_ZWRITE_ENABLED)
  858. {
  859. DBG_D3D((8, " Disabling Z Writes"));
  860. *pFlags &= ~CTXT_HAS_ZWRITE_ENABLED;
  861. DIRTY_ZBUFFER;
  862. }
  863. }
  864. break;
  865. case D3DRENDERSTATE_ALPHATESTENABLE:
  866. DBG_D3D((8, "ChangeState: Alpha Test Enable "
  867. "(BOOL) 0x%x",dwRSVal));
  868. NOT_HANDLED;
  869. break;
  870. case D3DRENDERSTATE_LASTPIXEL:
  871. // True for last pixel on lines
  872. DBG_D3D((8, "ChangeState: Last Pixel "
  873. "(BOOL) 0x%x",dwRSVal));
  874. if (dwRSVal)
  875. {
  876. *pFlags |= CTXT_HAS_LASTPIXEL_ENABLED;
  877. }
  878. else
  879. {
  880. *pFlags &= ~CTXT_HAS_LASTPIXEL_ENABLED;
  881. }
  882. break;
  883. case D3DRENDERSTATE_TEXTUREMAG:
  884. DBG_D3D((8, "ChangeState: Texture magnification "
  885. "(D3DTEXTUREFILTER) 0x%x",dwRSVal));
  886. switch(dwRSVal) {
  887. case D3DFILTER_NEAREST:
  888. case D3DFILTER_MIPNEAREST:
  889. pContext->bMagFilter = FALSE;
  890. pSoftPermedia->TextureReadMode.FilterMode = 0;
  891. break;
  892. case D3DFILTER_LINEAR:
  893. case D3DFILTER_MIPLINEAR:
  894. case D3DFILTER_LINEARMIPNEAREST:
  895. case D3DFILTER_LINEARMIPLINEAR:
  896. pContext->bMagFilter = TRUE;
  897. pSoftPermedia->TextureReadMode.FilterMode = 1;
  898. break;
  899. default:
  900. break;
  901. }
  902. DIRTY_TEXTURE;
  903. break;
  904. case D3DRENDERSTATE_TEXTUREMIN:
  905. DBG_D3D((8, "ChangeState: Texture minification "
  906. "(D3DTEXTUREFILTER) 0x%x",dwRSVal));
  907. switch(dwRSVal) {
  908. case D3DFILTER_NEAREST:
  909. case D3DFILTER_MIPNEAREST:
  910. pContext->bMinFilter = FALSE;
  911. break;
  912. case D3DFILTER_MIPLINEAR:
  913. case D3DFILTER_LINEAR:
  914. case D3DFILTER_LINEARMIPNEAREST:
  915. case D3DFILTER_LINEARMIPLINEAR:
  916. pContext->bMinFilter = TRUE;
  917. break;
  918. default:
  919. break;
  920. }
  921. DIRTY_TEXTURE;
  922. break;
  923. case D3DRENDERSTATE_SRCBLEND:
  924. DBG_D3D((8, "ChangeState: Source Blend (D3DBLEND):"));
  925. DECODEBLEND(4, dwRSVal);
  926. switch (dwRSVal) {
  927. case D3DBLEND_ZERO:
  928. pSoftPermedia->AlphaBlendMode.SourceBlend =
  929. __PERMEDIA_BLEND_FUNC_ZERO;
  930. break;
  931. case D3DBLEND_ONE:
  932. pSoftPermedia->AlphaBlendMode.SourceBlend =
  933. __PERMEDIA_BLEND_FUNC_ONE;
  934. break;
  935. case D3DBLEND_SRCALPHA:
  936. pSoftPermedia->AlphaBlendMode.SourceBlend =
  937. __PERMEDIA_BLEND_FUNC_SRC_ALPHA;
  938. break;
  939. default:
  940. DBG_D3D((2,"Invalid Source Blend! - %d",
  941. dwRSVal));
  942. break;
  943. }
  944. // If alpha is on, we may need to validate the chosen blend
  945. if (*pFlags & CTXT_HAS_ALPHABLEND_ENABLED)
  946. DIRTY_ALPHABLEND;
  947. break;
  948. case D3DRENDERSTATE_DESTBLEND:
  949. DBG_D3D((8, "ChangeState: Destination Blend (D3DBLEND):"));
  950. DECODEBLEND(4, dwRSVal);
  951. switch (dwRSVal) {
  952. case D3DBLEND_ZERO:
  953. pSoftPermedia->AlphaBlendMode.DestinationBlend =
  954. __PERMEDIA_BLEND_FUNC_ZERO;
  955. break;
  956. case D3DBLEND_ONE:
  957. pSoftPermedia->AlphaBlendMode.DestinationBlend =
  958. __PERMEDIA_BLEND_FUNC_ONE;
  959. break;
  960. case D3DBLEND_INVSRCALPHA:
  961. pSoftPermedia->AlphaBlendMode.DestinationBlend =
  962. __PERMEDIA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  963. break;
  964. default:
  965. DBG_D3D((2,"Invalid Dest Blend! - %d", dwRSVal));
  966. break;
  967. }
  968. // If alpha is on, we may need to validate the chosen blend
  969. if (*pFlags & CTXT_HAS_ALPHABLEND_ENABLED)
  970. DIRTY_ALPHABLEND;
  971. break;
  972. case D3DRENDERSTATE_CULLMODE:
  973. DBG_D3D((8, "ChangeState: Cull Mode "
  974. "(D3DCULL) 0x%x",dwRSVal));
  975. pContext->CullMode = (D3DCULL) dwRSVal;
  976. switch(dwRSVal) {
  977. case D3DCULL_NONE:
  978. #ifdef P2_CHIP_CULLING
  979. pSoftPermedia->DeltaMode.BackfaceCull = 0;
  980. #endif
  981. break;
  982. case D3DCULL_CCW:
  983. #ifdef P2_CHIP_CULLING
  984. RENDER_NEGATIVE_CULL(pContext->RenderCommand);
  985. pSoftPermedia->DeltaMode.BackfaceCull = 1;
  986. #endif
  987. break;
  988. case D3DCULL_CW:
  989. #ifdef P2_CHIP_CULLING
  990. RENDER_POSITIVE_CULL(pContext->RenderCommand);
  991. pSoftPermedia->DeltaMode.BackfaceCull = 1;
  992. #endif
  993. break;
  994. }
  995. RESERVEDMAPTR(1);
  996. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  997. COMMITDMAPTR();
  998. break;
  999. case D3DRENDERSTATE_ZFUNC:
  1000. DBG_D3D((8, "ChangeState: Z Compare function "
  1001. "(D3DCMPFUNC) 0x%x",dwRSVal));
  1002. switch (dwRSVal) {
  1003. case D3DCMP_NEVER:
  1004. pSoftPermedia->DepthMode.CompareMode =
  1005. __PERMEDIA_DEPTH_COMPARE_MODE_NEVER;
  1006. break;
  1007. case D3DCMP_LESS:
  1008. pSoftPermedia->DepthMode.CompareMode =
  1009. __PERMEDIA_DEPTH_COMPARE_MODE_LESS;
  1010. break;
  1011. case D3DCMP_EQUAL:
  1012. pSoftPermedia->DepthMode.CompareMode =
  1013. __PERMEDIA_DEPTH_COMPARE_MODE_EQUAL;
  1014. break;
  1015. case D3DCMP_LESSEQUAL:
  1016. pSoftPermedia->DepthMode.CompareMode =
  1017. __PERMEDIA_DEPTH_COMPARE_MODE_LESS_OR_EQUAL;
  1018. break;
  1019. case D3DCMP_GREATER:
  1020. pSoftPermedia->DepthMode.CompareMode =
  1021. __PERMEDIA_DEPTH_COMPARE_MODE_GREATER;
  1022. break;
  1023. case D3DCMP_NOTEQUAL:
  1024. pSoftPermedia->DepthMode.CompareMode =
  1025. __PERMEDIA_DEPTH_COMPARE_MODE_NOT_EQUAL;
  1026. break;
  1027. case D3DCMP_GREATEREQUAL:
  1028. pSoftPermedia->DepthMode.CompareMode =
  1029. __PERMEDIA_DEPTH_COMPARE_MODE_GREATER_OR_EQUAL;
  1030. break;
  1031. case D3DCMP_ALWAYS:
  1032. pSoftPermedia->DepthMode.CompareMode =
  1033. __PERMEDIA_DEPTH_COMPARE_MODE_ALWAYS;
  1034. break;
  1035. default:
  1036. pSoftPermedia->DepthMode.CompareMode =
  1037. __PERMEDIA_DEPTH_COMPARE_MODE_LESS_OR_EQUAL;
  1038. break;
  1039. }
  1040. DIRTY_ZBUFFER;
  1041. break;
  1042. case D3DRENDERSTATE_ALPHAREF:
  1043. DBG_D3D((8, "ChangeState: Alpha Reference "
  1044. "(D3DFIXED) 0x%x",dwRSVal));
  1045. NOT_HANDLED;
  1046. break;
  1047. case D3DRENDERSTATE_ALPHAFUNC:
  1048. DBG_D3D((8, "ChangeState: Alpha compare function "
  1049. "(D3DCMPFUNC) 0x%x",dwRSVal));
  1050. NOT_HANDLED;
  1051. break;
  1052. case D3DRENDERSTATE_DITHERENABLE:
  1053. DBG_D3D((8, "ChangeState: Dither Enable "
  1054. "(BOOL) 0x%x",dwRSVal));
  1055. if (dwRSVal != 0)
  1056. {
  1057. pSoftPermedia->DitherMode.DitherEnable = DITHER_ENABLE;
  1058. }
  1059. else
  1060. {
  1061. pSoftPermedia->DitherMode.DitherEnable = 0;
  1062. }
  1063. RESERVEDMAPTR(1);
  1064. COPY_PERMEDIA_DATA(DitherMode, pSoftPermedia->DitherMode);
  1065. COMMITDMAPTR();
  1066. break;
  1067. case D3DRENDERSTATE_COLORKEYENABLE:
  1068. DBG_D3D((8, "ChangeState: ColorKey Enable "
  1069. "(BOOL) 0x%x",dwRSVal));
  1070. DIRTY_TEXTURE;
  1071. break;
  1072. case D3DRENDERSTATE_MIPMAPLODBIAS:
  1073. DBG_D3D((8, "ChangeState: Mipmap LOD Bias "
  1074. "(INT) 0x%x", dwRSVal));
  1075. NOT_HANDLED;
  1076. break;
  1077. case D3DRENDERSTATE_ALPHABLENDENABLE:
  1078. DBG_D3D((8, "ChangeState: Blend Enable "
  1079. "(BOOL) 0x%x",dwRSVal));
  1080. if (dwRSVal != 0)
  1081. {
  1082. if (!(*pFlags & CTXT_HAS_ALPHABLEND_ENABLED))
  1083. {
  1084. // Set the blend enable flag in the render context struct
  1085. *pFlags |= CTXT_HAS_ALPHABLEND_ENABLED;
  1086. DIRTY_ALPHABLEND;
  1087. }
  1088. }
  1089. else
  1090. {
  1091. if (*pFlags & CTXT_HAS_ALPHABLEND_ENABLED)
  1092. {
  1093. // Turn off blend enable flag in render context struct
  1094. *pFlags &= ~CTXT_HAS_ALPHABLEND_ENABLED;
  1095. DIRTY_ALPHABLEND;
  1096. }
  1097. }
  1098. break;
  1099. case D3DRENDERSTATE_FOGENABLE:
  1100. DBG_D3D((8, "ChangeState: Fog Enable "
  1101. "(BOOL) 0x%x",dwRSVal));
  1102. if (dwRSVal != 0)
  1103. {
  1104. *pFlags |= CTXT_HAS_FOGGING_ENABLED;
  1105. RENDER_FOG_ENABLE(pContext->RenderCommand);
  1106. }
  1107. else
  1108. {
  1109. *pFlags &= ~CTXT_HAS_FOGGING_ENABLED;
  1110. RENDER_FOG_DISABLE(pContext->RenderCommand);
  1111. }
  1112. DIRTY_TEXTURE;
  1113. break;
  1114. case D3DRENDERSTATE_FOGCOLOR:
  1115. DBG_D3D((8, "ChangeState: Fog Color "
  1116. "(D3DCOLOR) 0x%x",dwRSVal));
  1117. {
  1118. BYTE red, green, blue, alpha;
  1119. red = (BYTE)RGBA_GETRED(dwRSVal);
  1120. green = (BYTE)RGBA_GETGREEN(dwRSVal);
  1121. blue = (BYTE)RGBA_GETBLUE(dwRSVal);
  1122. alpha = (BYTE)RGBA_GETALPHA(dwRSVal);
  1123. DBG_D3D((4,"FogColor: Red 0x%x, Green 0x%x, Blue 0x%x",
  1124. red, green, blue));
  1125. RESERVEDMAPTR(1);
  1126. pSoftPermedia->FogColor = RGBA_MAKE(blue, green, red, alpha);
  1127. SEND_PERMEDIA_DATA(FogColor, pSoftPermedia->FogColor);
  1128. COMMITDMAPTR();
  1129. }
  1130. break;
  1131. case D3DRENDERSTATE_SPECULARENABLE:
  1132. DBG_D3D((8, "ChangeState: Specular Lighting "
  1133. "(BOOL) 0x%x",dwRSVal));
  1134. if (dwRSVal)
  1135. {
  1136. *pFlags |= CTXT_HAS_SPECULAR_ENABLED;
  1137. }
  1138. else
  1139. {
  1140. *pFlags &= ~CTXT_HAS_SPECULAR_ENABLED;
  1141. }
  1142. break;
  1143. case D3DRENDERSTATE_FILLMODE:
  1144. DBG_D3D((8, "ChangeState: Fill Mode 0x%x",dwRSVal));
  1145. pContext->Hdr.FillMode = dwRSVal;
  1146. RESERVEDMAPTR(1);
  1147. switch (dwRSVal) {
  1148. case D3DFILL_POINT:
  1149. DBG_D3D((4, "RM = Point"));
  1150. // Restore the RasterizerMode
  1151. SEND_PERMEDIA_DATA(RasterizerMode, 0);
  1152. break;
  1153. case D3DFILL_WIREFRAME:
  1154. DBG_D3D((4, "RM = Wire"));
  1155. // Add nearly a half in the delta case for lines
  1156. // (lines aren't biased on a delta).
  1157. SEND_PERMEDIA_DATA(RasterizerMode, BIAS_NEARLY_HALF);
  1158. break;
  1159. case D3DFILL_SOLID:
  1160. DBG_D3D((4, "RM = Solid"));
  1161. // Restore the RasterizerMode
  1162. SEND_PERMEDIA_DATA(RasterizerMode, 0);
  1163. break;
  1164. default:
  1165. // Illegal value
  1166. DBG_D3D((4, "RM = Nonsense"));
  1167. pContext->Hdr.FillMode = D3DFILL_SOLID;
  1168. // Restore the RasterizerMode
  1169. SEND_PERMEDIA_DATA(RasterizerMode, 0);
  1170. break;
  1171. }
  1172. COMMITDMAPTR();
  1173. break;
  1174. case D3DRENDERSTATE_TEXTUREPERSPECTIVE:
  1175. DBG_D3D((8, "ChangeState: Texture Perspective "
  1176. "(BOOL) 0x%x",dwRSVal));
  1177. if (dwRSVal != 0)
  1178. {
  1179. pSoftPermedia->TextureAddressMode.PerspectiveCorrection = 1;
  1180. pSoftPermedia->DeltaMode.TextureParameterMode = 2; // Normalise
  1181. *pFlags |= CTXT_HAS_PERSPECTIVE_ENABLED;
  1182. }
  1183. else
  1184. {
  1185. pSoftPermedia->TextureAddressMode.PerspectiveCorrection = 0;
  1186. pSoftPermedia->DeltaMode.TextureParameterMode = 1; // Clamp
  1187. *pFlags &= ~CTXT_HAS_PERSPECTIVE_ENABLED;
  1188. }
  1189. RESERVEDMAPTR(3);
  1190. // Just to ensure that the texture unit
  1191. // can take the perspective change
  1192. COPY_PERMEDIA_DATA(LBWriteMode, pSoftPermedia->LBWriteMode);
  1193. COPY_PERMEDIA_DATA(TextureAddressMode,
  1194. pSoftPermedia->TextureAddressMode);
  1195. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  1196. COMMITDMAPTR();
  1197. break;
  1198. case D3DRENDERSTATE_ZENABLE:
  1199. DBG_D3D((8, "ChangeState: Z Enable "
  1200. "(TRUE) 0x%x",dwRSVal));
  1201. if (dwRSVal != 0)
  1202. {
  1203. if ( (!(*pFlags & CTXT_HAS_ZBUFFER_ENABLED)) &&
  1204. (pContext->ZBufferHandle) )
  1205. {
  1206. // Local Buffer Write mode
  1207. DBG_D3D((4, " Enabling Z Buffer"));
  1208. *pFlags |= CTXT_HAS_ZBUFFER_ENABLED;
  1209. DIRTY_ZBUFFER;
  1210. }
  1211. }
  1212. else
  1213. {
  1214. if (*pFlags & CTXT_HAS_ZBUFFER_ENABLED)
  1215. {
  1216. DBG_D3D((4, " Disabling Z Buffer"));
  1217. *pFlags &= ~CTXT_HAS_ZBUFFER_ENABLED;
  1218. DIRTY_ZBUFFER;
  1219. }
  1220. }
  1221. break;
  1222. case D3DRENDERSTATE_SHADEMODE:
  1223. DBG_D3D((8, "ChangeState: Shade mode "
  1224. "(D3DSHADEMODE) 0x%x",dwRSVal));
  1225. RESERVEDMAPTR(2);
  1226. switch(dwRSVal) {
  1227. case D3DSHADE_PHONG:
  1228. case D3DSHADE_GOURAUD:
  1229. if (!(*pFlags & CTXT_HAS_GOURAUD_ENABLED))
  1230. {
  1231. pSoftPermedia->ColorDDAMode.ShadeMode = 1;
  1232. // Set DDA to gouraud
  1233. COPY_PERMEDIA_DATA(ColorDDAMode,
  1234. pSoftPermedia->ColorDDAMode);
  1235. pSoftPermedia->DeltaMode.SmoothShadingEnable = 1;
  1236. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  1237. *pFlags |= CTXT_HAS_GOURAUD_ENABLED;
  1238. // If we are textureing, some changes may need to be made
  1239. if (pContext->CurrentTextureHandle != 0)
  1240. DIRTY_TEXTURE;
  1241. }
  1242. break;
  1243. case D3DSHADE_FLAT:
  1244. if (*pFlags & CTXT_HAS_GOURAUD_ENABLED)
  1245. {
  1246. pSoftPermedia->ColorDDAMode.ShadeMode = 0;
  1247. // Set DDA to flat
  1248. COPY_PERMEDIA_DATA(ColorDDAMode,
  1249. pSoftPermedia->ColorDDAMode);
  1250. pSoftPermedia->DeltaMode.SmoothShadingEnable = 0;
  1251. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  1252. *pFlags &= ~CTXT_HAS_GOURAUD_ENABLED;
  1253. // If we are textureing, some changes may need to be made
  1254. if (pContext->CurrentTextureHandle != 0)
  1255. DIRTY_TEXTURE;
  1256. }
  1257. break;
  1258. }
  1259. COMMITDMAPTR();
  1260. break;
  1261. case D3DRENDERSTATE_ROP2:
  1262. DBG_D3D((8, "ChangeState: ROP (D3DROP2) 0x%x",dwRSVal));
  1263. NOT_HANDLED;
  1264. break;
  1265. case D3DRENDERSTATE_ZVISIBLE:
  1266. // From DX6 onwards this is an obsolete render state.
  1267. // The D3D runtime does not support it anymore so drivers
  1268. // don't need to implement it
  1269. DBG_D3D((8, "ChangeState: Z Visible 0x%x",dwRSVal));
  1270. NOT_HANDLED;
  1271. break;
  1272. case D3DRENDERSTATE_PLANEMASK:
  1273. DBG_D3D((8, "ChangeState: Plane Mask "
  1274. "(ULONG) 0x%x",dwRSVal));
  1275. RESERVEDMAPTR(1);
  1276. SEND_PERMEDIA_DATA(FBHardwareWriteMask, (DWORD)dwRSVal);
  1277. COMMITDMAPTR();
  1278. break;
  1279. case D3DRENDERSTATE_MONOENABLE:
  1280. DBG_D3D((8, "ChangeState: Mono Raster enable "
  1281. "(BOOL) 0x%x", dwRSVal));
  1282. if (dwRSVal)
  1283. {
  1284. *pFlags |= CTXT_HAS_MONO_ENABLED;
  1285. }
  1286. else
  1287. {
  1288. *pFlags &= ~CTXT_HAS_MONO_ENABLED;
  1289. }
  1290. break;
  1291. case D3DRENDERSTATE_SUBPIXEL:
  1292. DBG_D3D((8, "ChangeState: SubPixel Correction "
  1293. "(BOOL) 0x%x", dwRSVal));
  1294. NOT_HANDLED;
  1295. break;
  1296. case D3DRENDERSTATE_SUBPIXELX:
  1297. DBG_D3D((8, "ChangeState: SubPixel Correction (xOnly) "
  1298. "(BOOL) 0x%x", dwRSVal));
  1299. NOT_HANDLED;
  1300. break;
  1301. #if D3D_STENCIL
  1302. //
  1303. // Stenciling Render States
  1304. //
  1305. case D3DRENDERSTATE_STENCILENABLE:
  1306. DBG_D3D((8, "ChangeState: Stencil Enable "
  1307. "(ULONG) 0x%x",dwRSVal));
  1308. if (dwRSVal != 0)
  1309. {
  1310. pSoftPermedia->StencilMode.UnitEnable = __PERMEDIA_ENABLE;
  1311. }
  1312. else
  1313. {
  1314. pSoftPermedia->StencilMode.UnitEnable = __PERMEDIA_DISABLE;
  1315. }
  1316. DIRTY_ZBUFFER;
  1317. break;
  1318. case D3DRENDERSTATE_STENCILFAIL:
  1319. DBG_D3D((8, "ChangeState: Stencil Fail Method "
  1320. "(ULONG) 0x%x",dwRSVal));
  1321. switch (dwRSVal) {
  1322. case D3DSTENCILOP_KEEP:
  1323. pSoftPermedia->StencilMode.SFail =
  1324. __PERMEDIA_STENCIL_METHOD_KEEP;
  1325. break;
  1326. case D3DSTENCILOP_ZERO:
  1327. pSoftPermedia->StencilMode.SFail =
  1328. __PERMEDIA_STENCIL_METHOD_ZERO;
  1329. break;
  1330. case D3DSTENCILOP_REPLACE:
  1331. pSoftPermedia->StencilMode.SFail =
  1332. __PERMEDIA_STENCIL_METHOD_REPLACE;
  1333. break;
  1334. case D3DSTENCILOP_INCRSAT:
  1335. case D3DSTENCILOP_INCR:
  1336. pSoftPermedia->StencilMode.SFail =
  1337. __PERMEDIA_STENCIL_METHOD_INCR;
  1338. break;
  1339. case D3DSTENCILOP_DECR:
  1340. case D3DSTENCILOP_DECRSAT:
  1341. pSoftPermedia->StencilMode.SFail =
  1342. __PERMEDIA_STENCIL_METHOD_DECR;
  1343. break;
  1344. case D3DSTENCILOP_INVERT:
  1345. pSoftPermedia->StencilMode.SFail =
  1346. __PERMEDIA_STENCIL_METHOD_INVERT;
  1347. break;
  1348. default:
  1349. DBG_D3D((2, " Unrecognized stencil method 0x%x",
  1350. dwRSVal));
  1351. }
  1352. DIRTY_ZBUFFER;
  1353. break;
  1354. case D3DRENDERSTATE_STENCILZFAIL:
  1355. DBG_D3D((8, "ChangeState: Stencil Pass Depth Fail Method "
  1356. "(ULONG) 0x%x",dwRSVal));
  1357. switch (dwRSVal) {
  1358. case D3DSTENCILOP_KEEP:
  1359. pSoftPermedia->StencilMode.DPFail =
  1360. __PERMEDIA_STENCIL_METHOD_KEEP;
  1361. break;
  1362. case D3DSTENCILOP_ZERO:
  1363. pSoftPermedia->StencilMode.DPFail =
  1364. __PERMEDIA_STENCIL_METHOD_ZERO;
  1365. break;
  1366. case D3DSTENCILOP_REPLACE:
  1367. pSoftPermedia->StencilMode.DPFail =
  1368. __PERMEDIA_STENCIL_METHOD_REPLACE;
  1369. break;
  1370. case D3DSTENCILOP_INCRSAT:
  1371. case D3DSTENCILOP_INCR:
  1372. pSoftPermedia->StencilMode.DPFail =
  1373. __PERMEDIA_STENCIL_METHOD_INCR;
  1374. break;
  1375. case D3DSTENCILOP_DECR:
  1376. case D3DSTENCILOP_DECRSAT:
  1377. pSoftPermedia->StencilMode.DPFail =
  1378. __PERMEDIA_STENCIL_METHOD_DECR;
  1379. break;
  1380. case D3DSTENCILOP_INVERT:
  1381. pSoftPermedia->StencilMode.DPFail =
  1382. __PERMEDIA_STENCIL_METHOD_INVERT;
  1383. break;
  1384. default:
  1385. DBG_D3D((2, " Unrecognized stencil method 0x%x",
  1386. dwRSVal));
  1387. }
  1388. DIRTY_ZBUFFER;
  1389. break;
  1390. case D3DRENDERSTATE_STENCILPASS:
  1391. DBG_D3D((8, "ChangeState: Stencil Pass Method "
  1392. "(ULONG) 0x%x",dwRSVal));
  1393. switch (dwRSVal) {
  1394. case D3DSTENCILOP_KEEP:
  1395. pSoftPermedia->StencilMode.DPPass =
  1396. __PERMEDIA_STENCIL_METHOD_KEEP;
  1397. break;
  1398. case D3DSTENCILOP_ZERO:
  1399. pSoftPermedia->StencilMode.DPPass =
  1400. __PERMEDIA_STENCIL_METHOD_ZERO;
  1401. break;
  1402. case D3DSTENCILOP_REPLACE:
  1403. pSoftPermedia->StencilMode.DPPass =
  1404. __PERMEDIA_STENCIL_METHOD_REPLACE;
  1405. break;
  1406. case D3DSTENCILOP_INCRSAT:
  1407. case D3DSTENCILOP_INCR:
  1408. pSoftPermedia->StencilMode.DPPass =
  1409. __PERMEDIA_STENCIL_METHOD_INCR;
  1410. break;
  1411. case D3DSTENCILOP_DECR:
  1412. case D3DSTENCILOP_DECRSAT:
  1413. pSoftPermedia->StencilMode.DPPass =
  1414. __PERMEDIA_STENCIL_METHOD_DECR;
  1415. break;
  1416. case D3DSTENCILOP_INVERT:
  1417. pSoftPermedia->StencilMode.DPPass =
  1418. __PERMEDIA_STENCIL_METHOD_INVERT;
  1419. break;
  1420. default:
  1421. DBG_D3D((2, " Unrecognized stencil method 0x%x",
  1422. dwRSVal));
  1423. }
  1424. DIRTY_ZBUFFER;
  1425. break;
  1426. case D3DRENDERSTATE_STENCILFUNC:
  1427. DBG_D3D((8, "ChangeState: Stencil Comparison Function "
  1428. "(ULONG) 0x%x",dwRSVal));
  1429. switch (dwRSVal) {
  1430. case D3DCMP_NEVER:
  1431. pSoftPermedia->StencilMode.CompareFunction =
  1432. __PERMEDIA_STENCIL_COMPARE_MODE_NEVER;
  1433. break;
  1434. case D3DCMP_LESS:
  1435. pSoftPermedia->StencilMode.CompareFunction =
  1436. __PERMEDIA_STENCIL_COMPARE_MODE_LESS;
  1437. break;
  1438. case D3DCMP_EQUAL:
  1439. pSoftPermedia->StencilMode.CompareFunction =
  1440. __PERMEDIA_STENCIL_COMPARE_MODE_EQUAL;
  1441. break;
  1442. case D3DCMP_LESSEQUAL:
  1443. pSoftPermedia->StencilMode.CompareFunction =
  1444. __PERMEDIA_STENCIL_COMPARE_MODE_LESS_OR_EQUAL;
  1445. break;
  1446. case D3DCMP_GREATER:
  1447. pSoftPermedia->StencilMode.CompareFunction =
  1448. __PERMEDIA_STENCIL_COMPARE_MODE_GREATER;
  1449. break;
  1450. case D3DCMP_NOTEQUAL:
  1451. pSoftPermedia->StencilMode.CompareFunction =
  1452. __PERMEDIA_STENCIL_COMPARE_MODE_NOT_EQUAL;
  1453. break;
  1454. case D3DCMP_GREATEREQUAL:
  1455. pSoftPermedia->StencilMode.CompareFunction =
  1456. __PERMEDIA_STENCIL_COMPARE_MODE_GREATER_OR_EQUAL;
  1457. break;
  1458. case D3DCMP_ALWAYS:
  1459. pSoftPermedia->StencilMode.CompareFunction =
  1460. __PERMEDIA_STENCIL_COMPARE_MODE_ALWAYS;
  1461. break;
  1462. default:
  1463. DBG_D3D((2, " Unrecognized stencil comparison function 0x%x",
  1464. dwRSVal));
  1465. }
  1466. DIRTY_ZBUFFER;
  1467. break;
  1468. case D3DRENDERSTATE_STENCILREF:
  1469. DBG_D3D((8, "ChangeState: Stencil Reference Value "
  1470. "(ULONG) 0x%x",dwRSVal));
  1471. pSoftPermedia->StencilData.ReferenceValue =
  1472. ( dwRSVal & 0x0001 );
  1473. DIRTY_ZBUFFER;
  1474. break;
  1475. case D3DRENDERSTATE_STENCILMASK:
  1476. DBG_D3D((8, "ChangeState: Stencil Compare Mask "
  1477. "(ULONG) 0x%x",dwRSVal));
  1478. pSoftPermedia->StencilData.CompareMask =
  1479. ( dwRSVal & 0x0001 );
  1480. DIRTY_ZBUFFER;
  1481. break;
  1482. case D3DRENDERSTATE_STENCILWRITEMASK:
  1483. DBG_D3D((8, "ChangeState: Stencil Write Mask "
  1484. "(ULONG) 0x%x",dwRSVal));
  1485. pSoftPermedia->StencilData.WriteMask =
  1486. ( dwRSVal & 0x0001 );
  1487. DIRTY_ZBUFFER;
  1488. break;
  1489. #endif // D3D_STENCIL
  1490. //
  1491. // Stippling
  1492. //
  1493. case D3DRENDERSTATE_STIPPLEDALPHA:
  1494. DBG_D3D((8, "ChangeState: Stippled Alpha "
  1495. "(BOOL) 0x%x",dwRSVal));
  1496. if (dwRSVal)
  1497. {
  1498. if (!(*pFlags & CTXT_HAS_ALPHASTIPPLE_ENABLED))
  1499. {
  1500. // Force a new start on the Alpha pattern
  1501. pContext->LastAlpha = 16;
  1502. *pFlags |= CTXT_HAS_ALPHASTIPPLE_ENABLED;
  1503. if (pContext->bKeptStipple == TRUE)
  1504. {
  1505. RENDER_AREA_STIPPLE_DISABLE(pContext->RenderCommand);
  1506. }
  1507. }
  1508. }
  1509. else
  1510. {
  1511. if (*pFlags & CTXT_HAS_ALPHASTIPPLE_ENABLED)
  1512. {
  1513. // If Alpha Stipple is being turned off, turn the normal
  1514. // stipple back on, and enable it.
  1515. int i;
  1516. RESERVEDMAPTR(8);
  1517. for (i = 0; i < 8; i++)
  1518. {
  1519. SEND_PERMEDIA_DATA_OFFSET(AreaStipplePattern0,
  1520. (DWORD)pContext->CurrentStipple[i], i);
  1521. }
  1522. COMMITDMAPTR();
  1523. *pFlags &= ~CTXT_HAS_ALPHASTIPPLE_ENABLED;
  1524. if (pContext->bKeptStipple == TRUE)
  1525. {
  1526. RENDER_AREA_STIPPLE_ENABLE(pContext->RenderCommand);
  1527. }
  1528. }
  1529. }
  1530. break;
  1531. case D3DRENDERSTATE_STIPPLEENABLE:
  1532. DBG_D3D((8, "ChangeState: Stipple Enable "
  1533. "(BOOL) 0x%x", dwRSVal));
  1534. if (dwRSVal)
  1535. {
  1536. if (!(*pFlags & CTXT_HAS_ALPHASTIPPLE_ENABLED))
  1537. {
  1538. RENDER_AREA_STIPPLE_ENABLE(pContext->RenderCommand);
  1539. }
  1540. pContext->bKeptStipple = TRUE;
  1541. }
  1542. else
  1543. {
  1544. RENDER_AREA_STIPPLE_DISABLE(pContext->RenderCommand);
  1545. pContext->bKeptStipple = FALSE;
  1546. }
  1547. break;
  1548. case D3DRENDERSTATE_CLIPPING:
  1549. DBG_D3D((8, "ChangeState: Clipping 0x%x",dwRSVal));
  1550. NOT_HANDLED;
  1551. break;
  1552. case D3DRENDERSTATE_LIGHTING:
  1553. DBG_D3D((8, "ChangeState: Lighting 0x%x",dwRSVal));
  1554. NOT_HANDLED;
  1555. break;
  1556. case D3DRENDERSTATE_EXTENTS:
  1557. DBG_D3D((8, "ChangeState: Extents 0x%x",dwRSVal));
  1558. NOT_HANDLED;
  1559. break;
  1560. case D3DRENDERSTATE_AMBIENT:
  1561. DBG_D3D((8, "ChangeState: Ambient 0x%x",dwRSVal));
  1562. NOT_HANDLED;
  1563. break;
  1564. case D3DRENDERSTATE_FOGVERTEXMODE:
  1565. DBG_D3D((8, "ChangeState: Fog Vertex Mode 0x%x",dwRSVal));
  1566. NOT_HANDLED;
  1567. break;
  1568. case D3DRENDERSTATE_COLORVERTEX:
  1569. DBG_D3D((8, "ChangeState: Color Vertex 0x%x",dwRSVal));
  1570. NOT_HANDLED;
  1571. break;
  1572. case D3DRENDERSTATE_LOCALVIEWER:
  1573. DBG_D3D((8, "ChangeState: LocalViewer 0x%x",dwRSVal));
  1574. NOT_HANDLED;
  1575. break;
  1576. case D3DRENDERSTATE_NORMALIZENORMALS:
  1577. DBG_D3D((8, "ChangeState: Normalize Normals 0x%x",dwRSVal));
  1578. NOT_HANDLED;
  1579. break;
  1580. case D3DRENDERSTATE_COLORKEYBLENDENABLE:
  1581. DBG_D3D((8, "ChangeState: Colorkey Blend Enable 0x%x",dwRSVal));
  1582. NOT_HANDLED;
  1583. break;
  1584. case D3DRENDERSTATE_DIFFUSEMATERIALSOURCE:
  1585. DBG_D3D((8, "ChangeState: Diffuse Material Source 0x%x",dwRSVal));
  1586. NOT_HANDLED;
  1587. break;
  1588. case D3DRENDERSTATE_SPECULARMATERIALSOURCE:
  1589. DBG_D3D((8, "ChangeState: Specular Material Source 0x%x",dwRSVal));
  1590. NOT_HANDLED;
  1591. break;
  1592. case D3DRENDERSTATE_AMBIENTMATERIALSOURCE:
  1593. DBG_D3D((8, "ChangeState: Ambient Material Source 0x%x",dwRSVal));
  1594. NOT_HANDLED;
  1595. break;
  1596. case D3DRENDERSTATE_EMISSIVEMATERIALSOURCE:
  1597. DBG_D3D((8, "ChangeState: Emmisive Material Source 0x%x",dwRSVal));
  1598. NOT_HANDLED;
  1599. break;
  1600. case D3DRENDERSTATE_VERTEXBLEND:
  1601. DBG_D3D((8, "ChangeState: Vertex Blend 0x%x",dwRSVal));
  1602. NOT_HANDLED;
  1603. break;
  1604. case D3DRENDERSTATE_CLIPPLANEENABLE:
  1605. DBG_D3D((8, "ChangeState: Clip Plane Enable 0x%x",dwRSVal));
  1606. NOT_HANDLED;
  1607. break;
  1608. case D3DRENDERSTATE_SCENECAPTURE:
  1609. // This state pass TRUE or FALSE to replace the functionality
  1610. // of D3DHALCallbacks->SceneCapture(), Permedia2 Hardware doesn't
  1611. // need begin/end scene information, therefore it's a NOOP here.
  1612. if (dwRSVal)
  1613. TextureCacheManagerResetStatCounters(pContext->pTextureManager);
  1614. DBG_D3D((8,"D3DRENDERSTATE_SCENECAPTURE=%x", (DWORD)dwRSVal));
  1615. NOT_HANDLED;
  1616. break;
  1617. case D3DRENDERSTATE_EVICTMANAGEDTEXTURES:
  1618. DBG_D3D((8,"D3DRENDERSTATE_EVICTMANAGEDTEXTURES=%x", (DWORD)dwRSVal));
  1619. if (NULL != pContext->pTextureManager)
  1620. TextureCacheManagerEvictTextures(pContext->pTextureManager);
  1621. break;
  1622. //@@BEGIN_DDKSPLIT
  1623. #if D3D_POINTSPRITES
  1624. case D3DRENDERSTATE_POINTSIZE:
  1625. DBG_D3D((8, "ChangeState: Point size 0x%x",dwRSVal));
  1626. (DWORD&)(pContext->fPointSize) = dwRSVal;
  1627. break;
  1628. case D3DRENDERSTATE_POINTSPRITE_ENABLE:
  1629. DBG_D3D((8, "ChangeState: Point Sprite Enable 0x%x",dwRSVal));
  1630. pContext->bPointSpriteEnabled = dwRSVal;
  1631. break;
  1632. // All of the following point sprite related render states are
  1633. // ignored by this driver since we are a Non-TnLHal driver.
  1634. case D3DRENDERSTATE_POINTATTENUATION_A:
  1635. DBG_D3D((8, "ChangeState: Point Attenuation A 0x%x",dwRSVal));
  1636. NOT_HANDLED;
  1637. break;
  1638. case D3DRENDERSTATE_POINTATTENUATION_B:
  1639. DBG_D3D((8, "ChangeState: Point Attenuation B 0x%x",dwRSVal));
  1640. NOT_HANDLED;
  1641. break;
  1642. case D3DRENDERSTATE_POINTATTENUATION_C:
  1643. DBG_D3D((8, "ChangeState: Point Attenuation C 0x%x",dwRSVal));
  1644. NOT_HANDLED;
  1645. break;
  1646. case D3DRENDERSTATE_POINTSIZEMIN:
  1647. DBG_D3D((8, "ChangeState: Point Size Min 0x%x",dwRSVal));
  1648. NOT_HANDLED;
  1649. break;
  1650. #endif // D3D_POINTSPRITES
  1651. //@@END_DDKSPLIT
  1652. case D3DRENDERSTATE_WRAP0:
  1653. case D3DRENDERSTATE_WRAP1:
  1654. case D3DRENDERSTATE_WRAP2:
  1655. case D3DRENDERSTATE_WRAP3:
  1656. case D3DRENDERSTATE_WRAP4:
  1657. case D3DRENDERSTATE_WRAP5:
  1658. case D3DRENDERSTATE_WRAP6:
  1659. case D3DRENDERSTATE_WRAP7:
  1660. DBG_D3D((8, "ChangeState: Wrap(%x) "
  1661. "(BOOL) 0x%x",(dwRSType - D3DRENDERSTATE_WRAPBIAS ),dwRSVal));
  1662. pContext->dwWrap[dwRSType - D3DRENDERSTATE_WRAPBIAS] = dwRSVal;
  1663. break;
  1664. default:
  1665. if ((dwRSType >= D3DRENDERSTATE_STIPPLEPATTERN00) &&
  1666. (dwRSType <= D3DRENDERSTATE_STIPPLEPATTERN07))
  1667. {
  1668. DBG_D3D((8, "ChangeState: Loading Stipple0x%x with 0x%x",
  1669. dwRSType - D3DRENDERSTATE_STIPPLEPATTERN00,
  1670. (DWORD)dwRSVal));
  1671. pContext->CurrentStipple[(dwRSType - D3DRENDERSTATE_STIPPLEPATTERN00)] =
  1672. (BYTE)dwRSVal;
  1673. if (!(*pFlags & CTXT_HAS_ALPHASTIPPLE_ENABLED))
  1674. {
  1675. // Flat-Stippled Alpha is not on, so use the
  1676. // current stipple pattern
  1677. RESERVEDMAPTR(1);
  1678. SEND_PERMEDIA_DATA_OFFSET(AreaStipplePattern0,
  1679. (DWORD)dwRSVal,
  1680. dwRSType - D3DRENDERSTATE_STIPPLEPATTERN00);
  1681. COMMITDMAPTR();
  1682. }
  1683. }
  1684. else
  1685. {
  1686. DBG_D3D((2, "ChangeState: Unhandled opcode = %d", dwRSType));
  1687. }
  1688. break;
  1689. } // switch (dwRSType of renderstate)
  1690. // Mirror any change that happened in the render states into TSS 0
  1691. __MapRS_Into_TSS0(pContext, dwRSType, dwRSVal);
  1692. DBG_D3D((10,"Exiting __ProcessRenderStates"));
  1693. }
  1694. //-----------------------------------------------------------------------------
  1695. //
  1696. // DWORD __ProcessPermediaStates
  1697. //
  1698. // Handle render state changes that arrive through the D3DDP2OP_RENDERSTATE
  1699. // token in the DP2 command stream.
  1700. //
  1701. //-----------------------------------------------------------------------------
  1702. DWORD
  1703. __ProcessPermediaStates(PERMEDIA_D3DCONTEXT* pContext,
  1704. DWORD dwCount,
  1705. LPD3DSTATE lpState,
  1706. LPDWORD lpStateMirror)
  1707. {
  1708. DWORD dwRSType, dwRSVal, i;
  1709. DBG_D3D((10,"Entering __ProcessPermediaStates"));
  1710. DBG_D3D((4, "__ProcessPermediaStates: Processing %d State changes", dwCount));
  1711. // Loop through all renderstates passed in the DP2 command stream
  1712. for (i = 0; i < dwCount; i++, lpState++)
  1713. {
  1714. dwRSType = (DWORD) lpState->drstRenderStateType;
  1715. dwRSVal = (DWORD) lpState->dwArg[0];
  1716. DBG_D3D((8, "__ProcessPermediaStates state %d value = %d",
  1717. dwRSType, dwRSVal));
  1718. // Check validity of the render state
  1719. if (!VALID_STATE(dwRSType))
  1720. {
  1721. DBG_D3D((0, "state 0x%08x is invalid", dwRSType));
  1722. return DDERR_INVALIDPARAMS;
  1723. }
  1724. // Verify if state needs to be overrided or ignored
  1725. if (IS_OVERRIDE(dwRSType))
  1726. {
  1727. DWORD override = GET_OVERRIDE(dwRSType);
  1728. if (dwRSVal)
  1729. {
  1730. DBG_D3D((4, "in RenderState, setting override for state %d",
  1731. override));
  1732. STATESET_SET(pContext->overrides, override);
  1733. }
  1734. else
  1735. {
  1736. DBG_D3D((4, "in RenderState, clearing override for state %d",
  1737. override));
  1738. STATESET_CLEAR(pContext->overrides, override);
  1739. }
  1740. continue;
  1741. }
  1742. if (STATESET_ISSET(pContext->overrides, dwRSType))
  1743. {
  1744. DBG_D3D((4, "in RenderState, state %d is overridden, ignoring",
  1745. dwRSType));
  1746. continue;
  1747. }
  1748. #if D3D_STATEBLOCKS
  1749. if (!pContext->bStateRecMode)
  1750. {
  1751. #endif D3D_STATEBLOCKS
  1752. // Store the state in the context
  1753. pContext->RenderStates[dwRSType] = dwRSVal;
  1754. // Mirror value
  1755. if ( lpStateMirror )
  1756. lpStateMirror[dwRSType] = dwRSVal;
  1757. __ProcessRenderStates(pContext, dwRSType, dwRSVal);
  1758. #if D3D_STATEBLOCKS
  1759. }
  1760. else
  1761. {
  1762. if (pContext->pCurrSS != NULL)
  1763. {
  1764. DBG_D3D((6,"Recording RS %x = %x",dwRSType,dwRSVal));
  1765. // Recording the state in a stateblock
  1766. pContext->pCurrSS->u.uc.RenderStates[dwRSType] = dwRSVal;
  1767. FLAG_SET(pContext->pCurrSS->u.uc.bStoredRS,dwRSType);
  1768. }
  1769. }
  1770. #endif D3D_STATEBLOCKS
  1771. } // for (i)
  1772. DBG_D3D((10,"Exiting __ProcessPermediaStates"));
  1773. return DD_OK;
  1774. } // __ProcessPermediaStates
  1775. #if D3D_STATEBLOCKS
  1776. //-----------------------------------------------------------------------------
  1777. //
  1778. // P2StateSetRec *FindStateSet
  1779. //
  1780. // Find a state identified by dwHandle starting from pRootSS.
  1781. // If not found, returns NULL.
  1782. //
  1783. //-----------------------------------------------------------------------------
  1784. P2StateSetRec *FindStateSet(PERMEDIA_D3DCONTEXT* pContext,
  1785. DWORD dwHandle)
  1786. {
  1787. if (dwHandle <= pContext->dwMaxSSIndex)
  1788. return pContext->pIndexTableSS[dwHandle - 1];
  1789. else
  1790. {
  1791. DBG_D3D((2,"State set %x not found (Max = %x)",
  1792. dwHandle, pContext->dwMaxSSIndex));
  1793. return NULL;
  1794. }
  1795. }
  1796. //-----------------------------------------------------------------------------
  1797. //
  1798. // void DumpStateSet
  1799. //
  1800. // Dump info stored in a state set
  1801. //
  1802. //-----------------------------------------------------------------------------
  1803. #define ELEMS_IN_ARRAY(a) ((sizeof(a)/sizeof(a[0])))
  1804. void DumpStateSet(P2StateSetRec *pSSRec)
  1805. {
  1806. DWORD i;
  1807. DBG_D3D((0,"DumpStateSet %x, Id=%x bCompressed=%x",
  1808. pSSRec,pSSRec->dwHandle,pSSRec->bCompressed));
  1809. if (!pSSRec->bCompressed)
  1810. {
  1811. // uncompressed state set
  1812. // Dump render states values
  1813. for (i=0; i< MAX_STATE; i++)
  1814. {
  1815. DBG_D3D((0,"RS %x = %x",i, pSSRec->u.uc.RenderStates[i]));
  1816. }
  1817. // Dump TSS's values
  1818. for (i=0; i<= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
  1819. {
  1820. DBG_D3D((0,"TSS %x = %x",i, pSSRec->u.uc.TssStates[i]));
  1821. }
  1822. // Dump RS bit masks
  1823. for (i=0; i< ELEMS_IN_ARRAY(pSSRec->u.uc.bStoredRS); i++)
  1824. {
  1825. DBG_D3D((0,"bStoredRS[%x] = %x",i, pSSRec->u.uc.bStoredRS[i]));
  1826. }
  1827. // Dump TSS bit masks
  1828. for (i=0; i< ELEMS_IN_ARRAY(pSSRec->u.uc.bStoredTSS); i++)
  1829. {
  1830. DBG_D3D((0,"bStoredTSS[%x] = %x",i, pSSRec->u.uc.bStoredTSS[i]));
  1831. }
  1832. }
  1833. else
  1834. {
  1835. // compressed state set
  1836. DBG_D3D((0,"dwNumRS =%x dwNumTSS=%x",
  1837. pSSRec->u.cc.dwNumRS,pSSRec->u.cc.dwNumTSS));
  1838. // dump compressed state
  1839. for (i=0; i< pSSRec->u.cc.dwNumTSS + pSSRec->u.cc.dwNumRS; i++)
  1840. {
  1841. DBG_D3D((0,"RS/TSS %x = %x",
  1842. pSSRec->u.cc.pair[i].dwType,
  1843. pSSRec->u.cc.pair[i].dwValue));
  1844. }
  1845. }
  1846. }
  1847. //-----------------------------------------------------------------------------
  1848. //
  1849. // void AddStateSetIndexTableEntry
  1850. //
  1851. // Add an antry to the index table. If necessary, grow it.
  1852. //-----------------------------------------------------------------------------
  1853. void AddStateSetIndexTableEntry(PERMEDIA_D3DCONTEXT* pContext,
  1854. DWORD dwNewHandle,
  1855. P2StateSetRec *pNewSSRec)
  1856. {
  1857. DWORD dwNewSize;
  1858. P2StateSetRec **pNewIndexTableSS;
  1859. // If the current list is not large enough, we'll have to grow a new one.
  1860. if (dwNewHandle > pContext->dwMaxSSIndex)
  1861. {
  1862. // New size of our index table
  1863. // (round up dwNewHandle in steps of SSPTRS_PERPAGE)
  1864. dwNewSize = ((dwNewHandle -1 + SSPTRS_PERPAGE) / SSPTRS_PERPAGE)
  1865. * SSPTRS_PERPAGE;
  1866. // we have to grow our list
  1867. pNewIndexTableSS = (P2StateSetRec **)
  1868. ENGALLOCMEM( FL_ZERO_MEMORY,
  1869. dwNewSize*sizeof(P2StateSetRec *),
  1870. ALLOC_TAG);
  1871. if (!pNewIndexTableSS)
  1872. {
  1873. // we weren't able to grow the list so we will keep the old one
  1874. // and (sigh) forget about this state set since that is the
  1875. // safest thing to do. We will delete also the state set structure
  1876. // since no one will otherwise be able to find it later.
  1877. DBG_D3D((0,"Out of mem growing state set list,"
  1878. " droping current state set"));
  1879. ENGFREEMEM(pNewSSRec);
  1880. return;
  1881. }
  1882. if (pContext->pIndexTableSS)
  1883. {
  1884. // if we already had a previous list, we must transfer its data
  1885. memcpy(pNewIndexTableSS,
  1886. pContext->pIndexTableSS,
  1887. pContext->dwMaxSSIndex*sizeof(P2StateSetRec *));
  1888. //and get rid of it
  1889. ENGFREEMEM(pContext->pIndexTableSS);
  1890. }
  1891. // New index table data
  1892. pContext->pIndexTableSS = pNewIndexTableSS;
  1893. pContext->dwMaxSSIndex = dwNewSize;
  1894. }
  1895. // Store our state set pointer into our access list
  1896. pContext->pIndexTableSS[dwNewHandle - 1] = pNewSSRec;
  1897. }
  1898. //-----------------------------------------------------------------------------
  1899. //
  1900. // void CompressStateSet
  1901. //
  1902. // Compress a state set so it uses the minimum necessary space. Since we expect
  1903. // some apps to make extensive use of state sets we want to keep things tidy.
  1904. // Returns address of new structure (ir old, if it wasn't compressed)
  1905. //
  1906. //-----------------------------------------------------------------------------
  1907. P2StateSetRec * CompressStateSet(PERMEDIA_D3DCONTEXT* pContext,
  1908. P2StateSetRec *pUncompressedSS)
  1909. {
  1910. P2StateSetRec *pCompressedSS;
  1911. DWORD i, dwSize, dwIndex, dwCount;
  1912. // Create a new state set of just the right size we need
  1913. // Calculate how large
  1914. dwCount = 0;
  1915. for (i=0; i< MAX_STATE; i++)
  1916. if (IS_FLAG_SET(pUncompressedSS->u.uc.bStoredRS , i))
  1917. {
  1918. dwCount++;
  1919. };
  1920. for (i=0; i<= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
  1921. if (IS_FLAG_SET(pUncompressedSS->u.uc.bStoredTSS , i))
  1922. {
  1923. dwCount++;
  1924. };
  1925. // Create a new state set of just the right size we need
  1926. // ANY CHANGE MADE TO THE P2StateSetRec structure MUST BE REFLECTED HERE!
  1927. dwSize = 2*sizeof(DWORD) + // handle , flags
  1928. 2*sizeof(DWORD) + // # of RS & TSS
  1929. 2*dwCount*sizeof(DWORD); // compressed structure
  1930. if (dwSize >= sizeof(P2StateSetRec))
  1931. {
  1932. // it is not efficient to compress, leave uncompressed !
  1933. pUncompressedSS->bCompressed = FALSE;
  1934. return pUncompressedSS;
  1935. }
  1936. pCompressedSS = (P2StateSetRec *)ENGALLOCMEM( FL_ZERO_MEMORY,
  1937. dwSize, ALLOC_TAG);
  1938. if (pCompressedSS)
  1939. {
  1940. // adjust data in new compressed state set
  1941. pCompressedSS->bCompressed = TRUE;
  1942. pCompressedSS->dwHandle = pUncompressedSS->dwHandle;
  1943. // Transfer our info to this new state set
  1944. pCompressedSS->u.cc.dwNumRS = 0;
  1945. pCompressedSS->u.cc.dwNumTSS = 0;
  1946. dwIndex = 0;
  1947. for (i=0; i< MAX_STATE; i++)
  1948. if (IS_FLAG_SET(pUncompressedSS->u.uc.bStoredRS , i))
  1949. {
  1950. pCompressedSS->u.cc.pair[dwIndex].dwType = i;
  1951. pCompressedSS->u.cc.pair[dwIndex].dwValue =
  1952. pUncompressedSS->u.uc.RenderStates[i];
  1953. pCompressedSS->u.cc.dwNumRS++;
  1954. dwIndex++;
  1955. }
  1956. for (i=0; i<= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
  1957. if (IS_FLAG_SET(pUncompressedSS->u.uc.bStoredTSS , i))
  1958. {
  1959. pCompressedSS->u.cc.pair[dwIndex].dwType = i;
  1960. pCompressedSS->u.cc.pair[dwIndex].dwValue =
  1961. pUncompressedSS->u.uc.TssStates[i];
  1962. pCompressedSS->u.cc.dwNumTSS++;
  1963. dwIndex++;
  1964. }
  1965. // Get rid of the old(uncompressed) one
  1966. ENGFREEMEM(pUncompressedSS);
  1967. return pCompressedSS;
  1968. }
  1969. else
  1970. {
  1971. DBG_D3D((0,"Not enough memory left to compress D3D state set"));
  1972. pUncompressedSS->bCompressed = FALSE;
  1973. return pUncompressedSS;
  1974. }
  1975. }
  1976. //-----------------------------------------------------------------------------
  1977. //
  1978. // void __DeleteAllStateSets
  1979. //
  1980. // Delete any remaining state sets for cleanup purpouses
  1981. //
  1982. //-----------------------------------------------------------------------------
  1983. void __DeleteAllStateSets(PERMEDIA_D3DCONTEXT* pContext)
  1984. {
  1985. P2StateSetRec *pSSRec;
  1986. DWORD dwSSIndex;
  1987. DBG_D3D((10,"Entering __DeleteAllStateSets"));
  1988. if (pContext->pIndexTableSS)
  1989. {
  1990. for(dwSSIndex = 0; dwSSIndex < pContext->dwMaxSSIndex; dwSSIndex++)
  1991. {
  1992. if (pSSRec = pContext->pIndexTableSS[dwSSIndex])
  1993. {
  1994. ENGFREEMEM(pSSRec);
  1995. }
  1996. }
  1997. // free fast index table
  1998. ENGFREEMEM(pContext->pIndexTableSS);
  1999. }
  2000. DBG_D3D((10,"Exiting __DeleteAllStateSets"));
  2001. }
  2002. //-----------------------------------------------------------------------------
  2003. //
  2004. // void __BeginStateSet
  2005. //
  2006. // Create a new state set identified by dwParam and start recording states
  2007. //
  2008. //-----------------------------------------------------------------------------
  2009. void __BeginStateSet(PERMEDIA_D3DCONTEXT* pContext, DWORD dwParam)
  2010. {
  2011. DBG_D3D((10,"Entering __BeginStateSet dwParam=%08lx",dwParam));
  2012. P2StateSetRec *pSSRec;
  2013. // Create a new state set
  2014. pSSRec = (P2StateSetRec *)ENGALLOCMEM( FL_ZERO_MEMORY,
  2015. sizeof(P2StateSetRec), ALLOC_TAG);
  2016. if (!pSSRec)
  2017. {
  2018. DBG_D3D((0,"Run out of memory for additional state sets"));
  2019. return;
  2020. }
  2021. // remember handle to current state set
  2022. pSSRec->dwHandle = dwParam;
  2023. pSSRec->bCompressed = FALSE;
  2024. // Get pointer to current recording state set
  2025. pContext->pCurrSS = pSSRec;
  2026. // Start recording mode
  2027. pContext->bStateRecMode = TRUE;
  2028. DBG_D3D((10,"Exiting __BeginStateSet"));
  2029. }
  2030. //-----------------------------------------------------------------------------
  2031. //
  2032. // void __EndStateSet
  2033. //
  2034. // stop recording states - revert to executing them.
  2035. //
  2036. //-----------------------------------------------------------------------------
  2037. void __EndStateSet(PERMEDIA_D3DCONTEXT* pContext)
  2038. {
  2039. DWORD dwHandle;
  2040. P2StateSetRec *pNewSSRec;
  2041. DBG_D3D((10,"Entering __EndStateSet"));
  2042. if (pContext->pCurrSS)
  2043. {
  2044. dwHandle = pContext->pCurrSS->dwHandle;
  2045. // compress the current state set
  2046. // Note: after being compressed the uncompressed version is free'd.
  2047. pNewSSRec = CompressStateSet(pContext, pContext->pCurrSS);
  2048. AddStateSetIndexTableEntry(pContext, dwHandle, pNewSSRec);
  2049. }
  2050. // No state set being currently recorded
  2051. pContext->pCurrSS = NULL;
  2052. // End recording mode
  2053. pContext->bStateRecMode = FALSE;
  2054. DBG_D3D((10,"Exiting __EndStateSet"));
  2055. }
  2056. //-----------------------------------------------------------------------------
  2057. //
  2058. // void __DeleteStateSet
  2059. //
  2060. // Delete the recorder state ste identified by dwParam
  2061. //
  2062. //-----------------------------------------------------------------------------
  2063. void __DeleteStateSet(PERMEDIA_D3DCONTEXT* pContext, DWORD dwParam)
  2064. {
  2065. DBG_D3D((10,"Entering __DeleteStateSet dwParam=%08lx",dwParam));
  2066. P2StateSetRec *pSSRec;
  2067. DWORD i;
  2068. if (pSSRec = FindStateSet(pContext, dwParam))
  2069. {
  2070. // Clear index table entry
  2071. pContext->pIndexTableSS[dwParam - 1] = NULL;
  2072. // Now delete the actual state set structure
  2073. ENGFREEMEM(pSSRec);
  2074. }
  2075. DBG_D3D((10,"Exiting __DeleteStateSet"));
  2076. }
  2077. //-----------------------------------------------------------------------------
  2078. //
  2079. // void __ExecuteStateSet
  2080. //
  2081. //
  2082. //-----------------------------------------------------------------------------
  2083. void __ExecuteStateSet(PERMEDIA_D3DCONTEXT* pContext, DWORD dwParam)
  2084. {
  2085. DBG_D3D((10,"Entering __ExecuteStateSet dwParam=%08lx",dwParam));
  2086. P2StateSetRec *pSSRec;
  2087. DWORD i;
  2088. if (pSSRec = FindStateSet(pContext, dwParam))
  2089. {
  2090. if (!pSSRec->bCompressed)
  2091. {
  2092. // uncompressed state set
  2093. // Execute any necessary render states
  2094. for (i=0; i< MAX_STATE; i++)
  2095. if (IS_FLAG_SET(pSSRec->u.uc.bStoredRS , i))
  2096. {
  2097. DWORD dwRSType, dwRSVal;
  2098. dwRSType = i;
  2099. dwRSVal = pSSRec->u.uc.RenderStates[dwRSType];
  2100. // Store the state in the context
  2101. pContext->RenderStates[dwRSType] = dwRSVal;
  2102. DBG_D3D((6,"__ExecuteStateSet RS %x = %x",
  2103. dwRSType, dwRSVal));
  2104. // Process it
  2105. __ProcessRenderStates(pContext, dwRSType, dwRSVal);
  2106. DIRTY_TEXTURE;
  2107. DIRTY_ZBUFFER;
  2108. DIRTY_ALPHABLEND;
  2109. }
  2110. // Execute any necessary TSS's
  2111. for (i=0; i<= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
  2112. if (IS_FLAG_SET(pSSRec->u.uc.bStoredTSS , i))
  2113. {
  2114. DWORD dwTSState, dwValue;
  2115. dwTSState = i;
  2116. dwValue = pSSRec->u.uc.TssStates[dwTSState];
  2117. DBG_D3D((6,"__ExecuteStateSet TSS %x = %x",
  2118. dwTSState, dwValue));
  2119. // Store value associated to this stage state
  2120. pContext->TssStates[dwTSState] = dwValue;
  2121. // Perform any necessary preprocessing of it
  2122. __HWPreProcessTSS(pContext, 0, dwTSState, dwValue);
  2123. DIRTY_TEXTURE;
  2124. }
  2125. // Execute any necessary state for lights, materials, transforms,
  2126. // viewport info, z range and clip planes - here -
  2127. }
  2128. else
  2129. {
  2130. // compressed state set
  2131. // Execute any necessary render states
  2132. for (i=0; i< pSSRec->u.cc.dwNumRS; i++)
  2133. {
  2134. DWORD dwRSType, dwRSVal;
  2135. dwRSType = pSSRec->u.cc.pair[i].dwType;
  2136. dwRSVal = pSSRec->u.cc.pair[i].dwValue;
  2137. // Store the state in the context
  2138. pContext->RenderStates[dwRSType] = dwRSVal;
  2139. DBG_D3D((6,"__ExecuteStateSet RS %x = %x",
  2140. dwRSType, dwRSVal));
  2141. // Process it
  2142. __ProcessRenderStates(pContext, dwRSType, dwRSVal);
  2143. DIRTY_TEXTURE;
  2144. DIRTY_ZBUFFER;
  2145. DIRTY_ALPHABLEND;
  2146. }
  2147. // Execute any necessary TSS's
  2148. for (; i< pSSRec->u.cc.dwNumTSS + pSSRec->u.cc.dwNumRS; i++)
  2149. {
  2150. DWORD dwTSState, dwValue;
  2151. dwTSState = pSSRec->u.cc.pair[i].dwType;
  2152. dwValue = pSSRec->u.cc.pair[i].dwValue;
  2153. DBG_D3D((6,"__ExecuteStateSet TSS %x = %x",
  2154. dwTSState, dwValue));
  2155. // Store value associated to this stage state
  2156. pContext->TssStates[dwTSState] = dwValue;
  2157. // Perform any necessary preprocessing of it
  2158. __HWPreProcessTSS(pContext, 0, dwTSState, dwValue);
  2159. DIRTY_TEXTURE;
  2160. }
  2161. // Execute any necessary state for lights, materials, transforms,
  2162. // viewport info, z range and clip planes - here -
  2163. }
  2164. }
  2165. DBG_D3D((10,"Exiting __ExecuteStateSet"));
  2166. }
  2167. //-----------------------------------------------------------------------------
  2168. //
  2169. // void __CaptureStateSet
  2170. //
  2171. //
  2172. //-----------------------------------------------------------------------------
  2173. void __CaptureStateSet(PERMEDIA_D3DCONTEXT* pContext, DWORD dwParam)
  2174. {
  2175. DBG_D3D((10,"Entering __CaptureStateSet dwParam=%08lx",dwParam));
  2176. P2StateSetRec *pSSRec;
  2177. DWORD i;
  2178. if (pSSRec = FindStateSet(pContext, dwParam))
  2179. {
  2180. if (!pSSRec->bCompressed)
  2181. {
  2182. // uncompressed state set
  2183. // Capture any necessary render states
  2184. for (i=0; i< MAX_STATE; i++)
  2185. if (IS_FLAG_SET(pSSRec->u.uc.bStoredRS , i))
  2186. {
  2187. pSSRec->u.uc.RenderStates[i] = pContext->RenderStates[i];
  2188. }
  2189. // Capture any necessary TSS's
  2190. for (i=0; i<= D3DTSS_TEXTURETRANSFORMFLAGS; i++)
  2191. if (IS_FLAG_SET(pSSRec->u.uc.bStoredTSS , i))
  2192. {
  2193. pSSRec->u.uc.TssStates[i] = pContext->TssStates[i];
  2194. }
  2195. // Capture any necessary state for lights, materials, transforms,
  2196. // viewport info, z range and clip planes - here -
  2197. }
  2198. else
  2199. {
  2200. // compressed state set
  2201. // Capture any necessary render states
  2202. for (i=0; i< pSSRec->u.cc.dwNumRS; i++)
  2203. {
  2204. DWORD dwRSType;
  2205. dwRSType = pSSRec->u.cc.pair[i].dwType;
  2206. pSSRec->u.cc.pair[i].dwValue = pContext->RenderStates[dwRSType];
  2207. }
  2208. // Capture any necessary TSS's
  2209. for (; i< pSSRec->u.cc.dwNumTSS + pSSRec->u.cc.dwNumRS; i++)
  2210. {
  2211. DWORD dwTSState;
  2212. dwTSState = pSSRec->u.cc.pair[i].dwType;
  2213. pSSRec->u.cc.pair[i].dwValue = pContext->TssStates[dwTSState];
  2214. }
  2215. // Capture any necessary state for lights, materials, transforms,
  2216. // viewport info, z range and clip planes - here -
  2217. }
  2218. }
  2219. DBG_D3D((10,"Exiting __CaptureStateSet"));
  2220. }
  2221. #endif //D3D_STATEBLOCKS