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.

2609 lines
110 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3dstate.c
  8. *
  9. * Content: D3D renderstates and texture stage states translation
  10. * into hardware specific settings.
  11. *
  12. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  13. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  14. \*****************************************************************************/
  15. #include "glint.h"
  16. #include "dma.h"
  17. #include "tag.h"
  18. //-----------------------------Public Routine----------------------------------
  19. //
  20. // D3DGetDriverState
  21. //
  22. // This callback is used by both the DirectDraw and Direct3D runtimes to obtain
  23. // information from the driver about its current state.
  24. // NOTE: We need to hook up this callback even if we don't do anything in it
  25. //
  26. // Parameter
  27. //
  28. // pgdsd
  29. // Pointer to a DD_GETDRIVERSTATEDATA structure.
  30. //
  31. // .dwFlags
  32. // Flags to indicate the data requested.
  33. // .lpDD
  34. // Pointer to a DD_DIRECTDRAW_GLOBAL structure describing the device.
  35. // .dwhContext
  36. // Specifies the ID of the context for which information is being
  37. // requested.
  38. // .lpdwStates
  39. // Pointer to the Direct3D driver state data to be filled in by the
  40. // driver.
  41. // .dwLength
  42. // Specifies the length of the state data to be filled in by the
  43. // driver.
  44. // .ddRVal
  45. // Specifies the return value.
  46. //
  47. //
  48. // Note: If you're driver doesn't implement this callback it won't be
  49. // recognized as a DX7 level driver
  50. //-----------------------------------------------------------------------------
  51. DWORD CALLBACK
  52. D3DGetDriverState(
  53. LPDDHAL_GETDRIVERSTATEDATA pgdsd)
  54. {
  55. P3_D3DCONTEXT* pContext;
  56. DBG_CB_ENTRY(D3DGetDriverState);
  57. #if DX7_TEXMANAGEMENT_STATS
  58. if (pgdsd->dwFlags == D3DDEVINFOID_TEXTUREMANAGER)
  59. {
  60. if (pgdsd->dwLength < sizeof(D3DDEVINFO_TEXTUREMANAGER))
  61. {
  62. DISPDBG((ERRLVL,"D3DGetDriverState dwLength=%d is not sufficient",
  63. pgdsd->dwLength));
  64. return DDHAL_DRIVER_NOTHANDLED;
  65. }
  66. pContext = _D3D_CTX_HandleToPtr(pgdsd->dwhContext);
  67. // Check if we got a valid context handle.
  68. if (!CHECK_D3DCONTEXT_VALIDITY(pContext))
  69. {
  70. pgdsd->ddRVal = D3DHAL_CONTEXT_BAD;
  71. DISPDBG((ERRLVL,"ERROR: Context not valid"));
  72. DBG_CB_EXIT(D3DGetDriverState, D3DHAL_CONTEXT_BAD);
  73. return (DDHAL_DRIVER_HANDLED);
  74. }
  75. // As the state buffer area lives in user memory, we need to
  76. // access it bracketing it with a try/except block. This
  77. // is because the user memory might under some circumstances
  78. // become invalid while the driver is running and then it
  79. // would AV. Also, the driver might need to do some cleanup
  80. // before returning to the OS.
  81. __try
  82. {
  83. _D3D_TM_STAT_GetStats(pContext,
  84. (LPD3DDEVINFO_TEXTUREMANAGER)pgdsd->lpdwStates);
  85. }
  86. __except(EXCEPTION_EXECUTE_HANDLER)
  87. {
  88. // On this driver we don't need to do anything special
  89. DISPDBG((ERRLVL,"Driver caused exception at "
  90. "line %u of file %s",
  91. __LINE__,__FILE__));
  92. pgdsd->ddRVal = DDERR_GENERIC;
  93. DBG_CB_EXIT(D3DGetDriverState,0);
  94. return DDHAL_DRIVER_NOTHANDLED;
  95. }
  96. pgdsd->ddRVal = DD_OK;
  97. DBG_CB_EXIT(D3DGetDriverState,0);
  98. return DDHAL_DRIVER_HANDLED;
  99. }
  100. #endif // DX7_TEXMANAGEMENT_STATS
  101. // Fall trough for any unhandled DEVICEINFOID's
  102. DISPDBG((ERRLVL,"D3DGetDriverState DEVICEINFOID=%08lx not supported",
  103. pgdsd->dwFlags));
  104. pgdsd->ddRVal = DDERR_UNSUPPORTED;
  105. DBG_CB_EXIT(D3DGetDriverState,0);
  106. return DDHAL_DRIVER_NOTHANDLED;
  107. } // D3DGetDriverState
  108. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  109. //-----------------------------------------------------------------------------
  110. //
  111. // _D3D_ST_CanRenderAntialiased
  112. //
  113. // Called when the D3DRENDERSTATE_ANTIALIAS RS is set to TRUE.
  114. //
  115. //-----------------------------------------------------------------------------
  116. BOOL
  117. _D3D_ST_CanRenderAntialiased(
  118. P3_D3DCONTEXT* pContext,
  119. BOOL bNewAliasBuffer)
  120. {
  121. P3_SOFTWARECOPY* pSoftPermedia = &pContext->SoftCopyGlint;
  122. P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
  123. P3_MEMREQUEST mmrq;
  124. DWORD dwResult;
  125. P3_DMA_DEFS();
  126. #if DX8_MULTISAMPLING
  127. // Only 4 multisampling is supported
  128. // And DX7 does not specifiy the number of samples.
  129. if (pContext->pSurfRenderInt->dwSampling != 4)
  130. {
  131. return FALSE;
  132. }
  133. #endif // DX8_MULTISAMPLING
  134. // Only allow AA rendering for 16-bit framebuffers with width and
  135. // height no larger than 1024. The size restriction comes because
  136. // later on we use the texture unit in order to shrink and filter
  137. // the resulting rendertarget. Since the maximum texture size
  138. // allowed in this hw is 2048, the maximum rendertarget we suppport
  139. // with antialiasing is 1024.
  140. if ((pContext->pSurfRenderInt->dwPixelSize != __GLINT_16BITPIXEL) ||
  141. (pContext->pSurfRenderInt->wWidth > 1024) ||
  142. (pContext->pSurfRenderInt->wHeight > 1024))
  143. {
  144. return FALSE;
  145. }
  146. // Do we need to release the current alias buffer
  147. if (bNewAliasBuffer)
  148. {
  149. if (pContext->dwAliasBackBuffer != 0)
  150. {
  151. _DX_LIN_FreeLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
  152. pContext->dwAliasBackBuffer);
  153. pContext->dwAliasBackBuffer = 0;
  154. pContext->dwAliasPixelOffset = 0;
  155. }
  156. if (pContext->dwAliasZBuffer != 0)
  157. {
  158. _DX_LIN_FreeLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
  159. pContext->dwAliasZBuffer);
  160. pContext->dwAliasZBuffer = 0;
  161. pContext->dwAliasZPixelOffset = 0;
  162. }
  163. }
  164. if ((pContext->pSurfRenderInt) && (! pContext->dwAliasBackBuffer))
  165. {
  166. // Allocate a 2x buffer if we need to
  167. memset(&mmrq, 0, sizeof(P3_MEMREQUEST));
  168. mmrq.dwSize = sizeof(P3_MEMREQUEST);
  169. mmrq.dwBytes = pContext->pSurfRenderInt->lPitch * 2 *
  170. pContext->pSurfRenderInt->wHeight * 2;
  171. mmrq.dwAlign = 8;
  172. mmrq.dwFlags = MEM3DL_FIRST_FIT;
  173. mmrq.dwFlags |= MEM3DL_FRONT;
  174. dwResult = _DX_LIN_AllocateLinearMemory(
  175. &pThisDisplay->LocalVideoHeap0Info,
  176. &mmrq);
  177. // Did we get the memory we asked for?
  178. if (dwResult != GLDD_SUCCESS)
  179. {
  180. return FALSE;
  181. }
  182. // Set up new backbuffer for antialiasing
  183. pContext->dwAliasBackBuffer = mmrq.pMem;
  184. pContext->dwAliasPixelOffset =
  185. pContext->dwAliasBackBuffer -
  186. pThisDisplay->dwScreenFlatAddr;
  187. }
  188. if ((pContext->pSurfZBufferInt) && (! pContext->dwAliasZBuffer))
  189. {
  190. memset(&mmrq, 0, sizeof(P3_MEMREQUEST));
  191. mmrq.dwSize = sizeof(P3_MEMREQUEST);
  192. mmrq.dwBytes = pContext->pSurfZBufferInt->lPitch * 2 *
  193. pContext->pSurfZBufferInt->wHeight * 2;
  194. mmrq.dwAlign = 8;
  195. mmrq.dwFlags = MEM3DL_FIRST_FIT;
  196. mmrq.dwFlags |= MEM3DL_FRONT;
  197. dwResult = _DX_LIN_AllocateLinearMemory(
  198. &pThisDisplay->LocalVideoHeap0Info,
  199. &mmrq);
  200. // Did we get the memory we asked for?
  201. if (dwResult == GLDD_SUCCESS)
  202. {
  203. pContext->dwAliasZBuffer = mmrq.pMem;
  204. pContext->dwAliasZPixelOffset =
  205. pContext->dwAliasZBuffer
  206. - pThisDisplay->dwScreenFlatAddr;
  207. }
  208. else
  209. {
  210. // Couldn't get the antialiasing memory for the backbuffer
  211. if (pContext->dwAliasBackBuffer != 0)
  212. {
  213. _DX_LIN_FreeLinearMemory(
  214. &pThisDisplay->LocalVideoHeap0Info,
  215. pContext->dwAliasBackBuffer);
  216. pContext->dwAliasBackBuffer = 0;
  217. pContext->dwAliasPixelOffset = 0;
  218. }
  219. // No enough resource for antialisde rendering
  220. return FALSE;
  221. }
  222. }
  223. return TRUE;
  224. } // _D3D_ST_CanRenderAntialiased
  225. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  226. //-----------------------------------------------------------------------------
  227. //
  228. // __ST_HandleDirtyP3State
  229. //
  230. // Setup any pending hardware state necessary to correctly render our primitives
  231. //
  232. //-----------------------------------------------------------------------------
  233. void
  234. __ST_HandleDirtyP3State(
  235. P3_THUNKEDDATA *pThisDisplay,
  236. P3_D3DCONTEXT *pContext)
  237. {
  238. P3_SOFTWARECOPY* pSoftP3RX = &pContext->SoftCopyGlint;
  239. P3_DMA_DEFS();
  240. DISPDBG((DBGLVL,"Permedia context Dirtied, setting states:"));
  241. // ********************************************************************
  242. // NOTE: MAINTAIN STRICT ORDERING OF THESE EVALUATIONS FOR HW REASONS!!
  243. // ********************************************************************
  244. if (pContext->dwDirtyFlags == CONTEXT_DIRTY_EVERYTHING)
  245. {
  246. // Everything needs re-doing - re-set the blend status.
  247. RESET_BLEND_ERROR(pContext);
  248. }
  249. //*********************************************************
  250. // Has the z buffer/stencil buffer configuration changed ???
  251. //*********************************************************
  252. if ((pContext->dwDirtyFlags & CONTEXT_DIRTY_ZBUFFER) ||
  253. (pContext->dwDirtyFlags & CONTEXT_DIRTY_STENCIL))
  254. {
  255. if ( ( (pContext->RenderStates[D3DRENDERSTATE_ZENABLE] == D3DZB_TRUE)
  256. || (pContext->RenderStates[D3DRENDERSTATE_ZENABLE] == D3DZB_USEW) )
  257. && (pContext->pSurfZBufferInt) )
  258. {
  259. // This includes W buffering as well as Z buffering.
  260. // The actual W-specific stuff is set up later.
  261. if (pContext->RenderStates[D3DRENDERSTATE_ZWRITEENABLE] == TRUE)
  262. {
  263. switch ((int)pSoftP3RX->P3RXDepthMode.CompareMode)
  264. {
  265. case __GLINT_DEPTH_COMPARE_MODE_ALWAYS:
  266. // Although it seems as though the ReadDestination can be
  267. // disabled, it can't. The result isn't correct because the
  268. // chip does a compare on the current value as an optimization
  269. // for updating the Z [CM].
  270. // NOTE! The P3 can actually do the optimisation if you
  271. // use some other flags. This needs fixing in the future.
  272. DISPDBG((ERRLVL,"** __ST_HandleDirtyP3State: "
  273. "please optimise the ZCMP_ALWAYS case"));
  274. pSoftP3RX->P3RXLBWriteMode.WriteEnable = __PERMEDIA_ENABLE;
  275. pSoftP3RX->P3RXLBDestReadMode.Enable = __PERMEDIA_ENABLE;
  276. pSoftP3RX->P3RXDepthMode.WriteMask = __PERMEDIA_ENABLE;
  277. break;
  278. case __GLINT_DEPTH_COMPARE_MODE_NEVER:
  279. pSoftP3RX->P3RXLBWriteMode.WriteEnable = __PERMEDIA_DISABLE;
  280. pSoftP3RX->P3RXLBDestReadMode.Enable = __PERMEDIA_DISABLE;
  281. pSoftP3RX->P3RXDepthMode.WriteMask = __PERMEDIA_DISABLE;
  282. break;
  283. default:
  284. pSoftP3RX->P3RXLBWriteMode.WriteEnable = __PERMEDIA_ENABLE;
  285. pSoftP3RX->P3RXLBDestReadMode.Enable = __PERMEDIA_ENABLE;
  286. pSoftP3RX->P3RXDepthMode.WriteMask = __PERMEDIA_ENABLE;
  287. break;
  288. }
  289. }
  290. else
  291. {
  292. if ( ( pSoftP3RX->P3RXDepthMode.CompareMode == __GLINT_DEPTH_COMPARE_MODE_NEVER )
  293. || ( pSoftP3RX->P3RXDepthMode.CompareMode == __GLINT_DEPTH_COMPARE_MODE_ALWAYS ) )
  294. {
  295. pSoftP3RX->P3RXLBDestReadMode.Enable = __PERMEDIA_DISABLE;
  296. }
  297. else
  298. {
  299. pSoftP3RX->P3RXLBDestReadMode.Enable = __PERMEDIA_ENABLE;
  300. }
  301. pSoftP3RX->P3RXLBWriteMode.WriteEnable = __PERMEDIA_DISABLE;
  302. pSoftP3RX->P3RXDepthMode.WriteMask = __PERMEDIA_DISABLE;
  303. }
  304. // Enable Z test
  305. pSoftP3RX->P3RXDepthMode.Enable = __PERMEDIA_ENABLE;
  306. }
  307. else
  308. {
  309. // ** Not Z Buffering
  310. // Disable Writes
  311. pSoftP3RX->P3RXLBWriteMode.WriteEnable = __PERMEDIA_DISABLE;
  312. pSoftP3RX->P3RXDepthMode.WriteMask = __PERMEDIA_DISABLE;
  313. // Disable Z test
  314. pSoftP3RX->P3RXDepthMode.Enable = __PERMEDIA_DISABLE;
  315. // No reads
  316. pSoftP3RX->P3RXLBDestReadMode.Enable = __PERMEDIA_DISABLE;
  317. }
  318. if (pContext->RenderStates[D3DRENDERSTATE_STENCILENABLE] != TRUE)
  319. {
  320. DISPDBG((DBGLVL,"Disabling Stencil"));
  321. pSoftP3RX->P3RXStencilMode.Enable = __PERMEDIA_DISABLE;
  322. }
  323. else
  324. {
  325. DISPDBG((DBGLVL,"Enabling Stencil"));
  326. pSoftP3RX->P3RXStencilMode.Enable = __PERMEDIA_ENABLE;
  327. pSoftP3RX->P3RXLBDestReadMode.Enable = __PERMEDIA_ENABLE;
  328. pSoftP3RX->P3RXLBWriteMode.WriteEnable = __PERMEDIA_ENABLE;
  329. switch(pContext->RenderStates[D3DRENDERSTATE_STENCILFAIL])
  330. {
  331. case D3DSTENCILOP_KEEP:
  332. pSoftP3RX->P3RXStencilMode.SFail = __GLINT_STENCIL_METHOD_KEEP;
  333. break;
  334. case D3DSTENCILOP_ZERO:
  335. pSoftP3RX->P3RXStencilMode.SFail = __GLINT_STENCIL_METHOD_ZERO;
  336. break;
  337. case D3DSTENCILOP_REPLACE:
  338. pSoftP3RX->P3RXStencilMode.SFail = __GLINT_STENCIL_METHOD_REPLACE;
  339. break;
  340. case D3DSTENCILOP_INCR:
  341. pSoftP3RX->P3RXStencilMode.SFail = __GLINT_STENCIL_METHOD_INCR_WRAP;
  342. break;
  343. case D3DSTENCILOP_INCRSAT:
  344. pSoftP3RX->P3RXStencilMode.SFail = __GLINT_STENCIL_METHOD_INCR;
  345. break;
  346. case D3DSTENCILOP_DECR:
  347. pSoftP3RX->P3RXStencilMode.SFail = __GLINT_STENCIL_METHOD_DECR_WRAP;
  348. break;
  349. case D3DSTENCILOP_DECRSAT:
  350. pSoftP3RX->P3RXStencilMode.SFail = __GLINT_STENCIL_METHOD_DECR;
  351. break;
  352. case D3DSTENCILOP_INVERT:
  353. pSoftP3RX->P3RXStencilMode.SFail = __GLINT_STENCIL_METHOD_INVERT;
  354. break;
  355. default:
  356. DISPDBG((ERRLVL,"ERROR: Illegal D3DRENDERSTATE_STENCILFAIL!"));
  357. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  358. break;
  359. }
  360. switch(pContext->RenderStates[D3DRENDERSTATE_STENCILZFAIL])
  361. {
  362. case D3DSTENCILOP_KEEP:
  363. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_KEEP;
  364. break;
  365. case D3DSTENCILOP_ZERO:
  366. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_ZERO;
  367. break;
  368. case D3DSTENCILOP_REPLACE:
  369. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_REPLACE;
  370. break;
  371. case D3DSTENCILOP_INCR:
  372. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_INCR_WRAP;
  373. break;
  374. case D3DSTENCILOP_INCRSAT:
  375. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_INCR;
  376. break;
  377. case D3DSTENCILOP_DECR:
  378. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_DECR_WRAP;
  379. break;
  380. case D3DSTENCILOP_DECRSAT:
  381. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_DECR;
  382. break;
  383. case D3DSTENCILOP_INVERT:
  384. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_INVERT;
  385. break;
  386. default:
  387. DISPDBG((ERRLVL,"ERROR: Illegal D3DRENDERSTATE_STENCILZFAIL!"));
  388. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  389. break;
  390. }
  391. switch(pContext->RenderStates[D3DRENDERSTATE_STENCILPASS])
  392. {
  393. case D3DSTENCILOP_KEEP:
  394. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_KEEP;
  395. break;
  396. case D3DSTENCILOP_ZERO:
  397. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_ZERO;
  398. break;
  399. case D3DSTENCILOP_REPLACE:
  400. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_REPLACE;
  401. break;
  402. case D3DSTENCILOP_INCR:
  403. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_INCR_WRAP;
  404. break;
  405. case D3DSTENCILOP_INCRSAT:
  406. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_INCR;
  407. break;
  408. case D3DSTENCILOP_DECR:
  409. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_DECR_WRAP;
  410. break;
  411. case D3DSTENCILOP_DECRSAT:
  412. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_DECR;
  413. break;
  414. case D3DSTENCILOP_INVERT:
  415. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_INVERT;
  416. break;
  417. default:
  418. DISPDBG((ERRLVL,"ERROR: Illegal D3DRENDERSTATE_STENCILPASS!"));
  419. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  420. break;
  421. }
  422. switch (pContext->RenderStates[D3DRENDERSTATE_STENCILFUNC])
  423. {
  424. case D3DCMP_NEVER:
  425. pSoftP3RX->P3RXStencilMode.CompareFunction = __GLINT_STENCIL_COMPARE_MODE_NEVER;
  426. break;
  427. case D3DCMP_LESS:
  428. pSoftP3RX->P3RXStencilMode.CompareFunction = __GLINT_STENCIL_COMPARE_MODE_LESS;
  429. break;
  430. case D3DCMP_EQUAL:
  431. pSoftP3RX->P3RXStencilMode.CompareFunction = __GLINT_STENCIL_COMPARE_MODE_EQUAL;
  432. break;
  433. case D3DCMP_LESSEQUAL:
  434. pSoftP3RX->P3RXStencilMode.CompareFunction = __GLINT_STENCIL_COMPARE_MODE_LESS_OR_EQUAL;
  435. break;
  436. case D3DCMP_GREATER:
  437. pSoftP3RX->P3RXStencilMode.CompareFunction = __GLINT_STENCIL_COMPARE_MODE_GREATER;
  438. break;
  439. case D3DCMP_NOTEQUAL:
  440. pSoftP3RX->P3RXStencilMode.CompareFunction = __GLINT_STENCIL_COMPARE_MODE_NOT_EQUAL;
  441. break;
  442. case D3DCMP_GREATEREQUAL:
  443. pSoftP3RX->P3RXStencilMode.CompareFunction = __GLINT_STENCIL_COMPARE_MODE_GREATER_OR_EQUAL;
  444. break;
  445. case D3DCMP_ALWAYS:
  446. pSoftP3RX->P3RXStencilMode.CompareFunction = __GLINT_STENCIL_COMPARE_MODE_ALWAYS;
  447. break;
  448. default:
  449. DISPDBG((ERRLVL,"ERROR: Unknown D3DRENDERSTATE_STENCILFUNC!"));
  450. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  451. break;
  452. }
  453. pSoftP3RX->P3RXStencilData.StencilWriteMask = (pContext->RenderStates[D3DRENDERSTATE_STENCILWRITEMASK] & 0xFF);
  454. pSoftP3RX->P3RXStencilData.CompareMask = (pContext->RenderStates[D3DRENDERSTATE_STENCILMASK] & 0xFF);
  455. pSoftP3RX->P3RXStencilData.ReferenceValue = (pContext->RenderStates[D3DRENDERSTATE_STENCILREF] & 0xFF);
  456. }
  457. P3_DMA_GET_BUFFER();
  458. P3_ENSURE_DX_SPACE(32);
  459. WAIT_FIFO(32);
  460. COPY_P3_DATA(DepthMode, pSoftP3RX->P3RXDepthMode);
  461. COPY_P3_DATA(LBDestReadMode, pSoftP3RX->P3RXLBDestReadMode);
  462. COPY_P3_DATA(LBWriteMode, pSoftP3RX->P3RXLBWriteMode);
  463. COPY_P3_DATA(LBReadFormat, pSoftP3RX->P3RXLBReadFormat);
  464. COPY_P3_DATA(LBWriteFormat, pSoftP3RX->P3RXLBWriteFormat);
  465. COPY_P3_DATA(StencilData, pSoftP3RX->P3RXStencilData);
  466. COPY_P3_DATA(StencilMode, pSoftP3RX->P3RXStencilMode);
  467. P3_DMA_COMMIT_BUFFER();
  468. }
  469. //*********************************************************
  470. // Has the alphatest type changed?
  471. //*********************************************************
  472. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_ALPHATEST)
  473. {
  474. DISPDBG((DBGLVL," Alpha testing"));
  475. P3_DMA_GET_BUFFER();
  476. P3_ENSURE_DX_SPACE(2);
  477. WAIT_FIFO(2);
  478. if (pContext->RenderStates[D3DRENDERSTATE_ALPHATESTENABLE] == FALSE)
  479. {
  480. pSoftP3RX->P3RXAlphaTestMode.Enable = __PERMEDIA_DISABLE;
  481. DISPDBG((DBGLVL,"Alpha test disabled, ChromaTest = %d",
  482. pContext->RenderStates[D3DRENDERSTATE_COLORKEYENABLE] ));
  483. }
  484. else
  485. {
  486. unsigned char ucChipAlphaRef;
  487. DWORD dwAlphaRef;
  488. if( pThisDisplay->dwDXVersion <= DX5_RUNTIME )
  489. {
  490. // Form 8 bit alpha reference value by scaling 1.16 fixed point to 0.8
  491. dwAlphaRef = pContext->RenderStates[D3DRENDERSTATE_ALPHAREF];
  492. // This conversion may need tweaking to cope with individual
  493. // apps' expectations. Fortunately, it's DX5 only, so there
  494. // are a finite number of them.
  495. if ( dwAlphaRef == 0x0000 )
  496. {
  497. ucChipAlphaRef = 0x00;
  498. }
  499. else if ( dwAlphaRef < 0xfe00 )
  500. {
  501. // Add the inverted top char to the bottom char, so that
  502. // the rounding changes smoothly all the way up to 0xfe00.
  503. dwAlphaRef += ~( dwAlphaRef >> 8 );
  504. ucChipAlphaRef = (unsigned char)( dwAlphaRef >> 8 );
  505. }
  506. else if ( dwAlphaRef < 0xffff )
  507. {
  508. // Clamp to make sure only 0xffff -> 0xff
  509. ucChipAlphaRef = 0xfe;
  510. }
  511. else
  512. {
  513. ucChipAlphaRef = 0xff;
  514. }
  515. DISPDBG((DBGLVL,"Alpha test enabled: Value = 0x%x, ChipAlphaRef = 0x%x",
  516. pContext->RenderStates[D3DRENDERSTATE_ALPHAREF],
  517. ucChipAlphaRef ));
  518. }
  519. else
  520. {
  521. // ALPHAREF is an 8 bit value on input - just copy straight into the chip
  522. dwAlphaRef = (unsigned char)pContext->RenderStates[D3DRENDERSTATE_ALPHAREF];
  523. if ( dwAlphaRef > 0xff )
  524. {
  525. ucChipAlphaRef = 0xff;
  526. }
  527. else
  528. {
  529. ucChipAlphaRef = (unsigned char)dwAlphaRef;
  530. }
  531. DISPDBG((DBGLVL,"Alpha test enabled: AlphaRef = 0x%x", ucChipAlphaRef ));
  532. }
  533. pSoftP3RX->P3RXAlphaTestMode.Reference = ucChipAlphaRef;
  534. pSoftP3RX->P3RXAlphaTestMode.Enable = __PERMEDIA_ENABLE;
  535. switch (pContext->RenderStates[D3DRENDERSTATE_ALPHAFUNC])
  536. {
  537. case D3DCMP_GREATER:
  538. DISPDBG((DBGLVL,"GREATER Alpha Test"));
  539. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_GREATER;
  540. break;
  541. case D3DCMP_GREATEREQUAL:
  542. DISPDBG((DBGLVL,"GREATEREQUAL Alpha Test"));
  543. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_GREATER_OR_EQUAL;
  544. break;
  545. case D3DCMP_LESS:
  546. DISPDBG((DBGLVL,"LESS Alpha Test"));
  547. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_LESS;
  548. break;
  549. case D3DCMP_LESSEQUAL:
  550. DISPDBG((DBGLVL,"LESSEQUAL Alpha Test"));
  551. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_LESS_OR_EQUAL;
  552. break;
  553. case D3DCMP_NOTEQUAL:
  554. DISPDBG((DBGLVL,"NOTEQUAL Alpha Test"));
  555. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_NOT_EQUAL;
  556. break;
  557. case D3DCMP_EQUAL:
  558. DISPDBG((DBGLVL,"EQUAL Alpha Test"));
  559. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_EQUAL;
  560. break;
  561. case D3DCMP_NEVER:
  562. DISPDBG((DBGLVL,"NEVER Alpha Test"));
  563. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_NEVER;
  564. break;
  565. case D3DCMP_ALWAYS:
  566. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_ALWAYS;
  567. break;
  568. default:
  569. DISPDBG((ERRLVL,"Unsuported AlphaTest mode"));
  570. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  571. break;
  572. }
  573. }
  574. COPY_P3_DATA(AlphaTestMode, pSoftP3RX->P3RXAlphaTestMode);
  575. P3_DMA_COMMIT_BUFFER();
  576. }
  577. //*********************************************************
  578. // Have the fogging parameters/state changed?
  579. //*********************************************************
  580. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_FOG)
  581. {
  582. if (!pContext->RenderStates[D3DRENDERSTATE_FOGENABLE])
  583. {
  584. pContext->Flags &= ~SURFACE_FOGENABLE;
  585. pSoftP3RX->P3RXFogMode.Table = __PERMEDIA_DISABLE;
  586. pSoftP3RX->P3RXFogMode.UseZ = __PERMEDIA_DISABLE;
  587. // Don't need delta to do fog value setup
  588. pSoftP3RX->P3RX_P3DeltaMode.FogEnable = __PERMEDIA_DISABLE;
  589. RENDER_FOG_DISABLE(pContext->RenderCommand);
  590. }
  591. else
  592. {
  593. DWORD CurrentEntry;
  594. DWORD TableEntry;
  595. float fEntry[256];
  596. float FogStart;
  597. float FogEnd;
  598. float FogDensity;
  599. LONG lWaitFifoEntries;
  600. float fValue;
  601. float z;
  602. float zIncrement;
  603. DWORD dwFogTableMode =
  604. pContext->RenderStates[D3DRENDERSTATE_FOGTABLEMODE];
  605. DWORD dwFogColor = pContext->RenderStates[D3DRENDERSTATE_FOGCOLOR];
  606. // Enable fog in the render command
  607. pContext->Flags |= SURFACE_FOGENABLE;
  608. RENDER_FOG_ENABLE(pContext->RenderCommand);
  609. DISPDBG((DBGLVL,"FogColor (BGR): 0x%x", dwFogColor));
  610. P3_DMA_GET_BUFFER_ENTRIES(2)
  611. SEND_P3_DATA(FogColor, RGBA_MAKE(RGBA_GETBLUE (dwFogColor),
  612. RGBA_GETGREEN(dwFogColor),
  613. RGBA_GETRED (dwFogColor),
  614. RGBA_GETALPHA(dwFogColor)) );
  615. P3_DMA_COMMIT_BUFFER();
  616. pSoftP3RX->P3RXFogMode.ZShift = 23; // Take the top 8 bits of the z value
  617. switch (dwFogTableMode)
  618. {
  619. case D3DFOG_NONE:
  620. pSoftP3RX->P3RXFogMode.Table = __PERMEDIA_DISABLE;
  621. pSoftP3RX->P3RXFogMode.UseZ = __PERMEDIA_DISABLE;
  622. pSoftP3RX->P3RXFogMode.InvertFI = __PERMEDIA_DISABLE;
  623. pSoftP3RX->P3RX_P3DeltaMode.FogEnable = __PERMEDIA_ENABLE;
  624. break;
  625. case D3DFOG_EXP:
  626. case D3DFOG_EXP2:
  627. case D3DFOG_LINEAR:
  628. pSoftP3RX->P3RXFogMode.Table = __PERMEDIA_ENABLE;
  629. pSoftP3RX->P3RXFogMode.UseZ = __PERMEDIA_ENABLE;
  630. pSoftP3RX->P3RXFogMode.InvertFI = __PERMEDIA_DISABLE;
  631. //pSoftP3RX->P3RX_P3DeltaMode.FogEnable = __PERMEDIA_DISABLE;
  632. // Don't need delta to do fog value setup (z is used as fog lookup)
  633. pSoftP3RX->P3RX_P3DeltaMode.FogEnable = __PERMEDIA_DISABLE;
  634. FogStart = pContext->fRenderStates[D3DRENDERSTATE_FOGTABLESTART];
  635. FogEnd = pContext->fRenderStates[D3DRENDERSTATE_FOGTABLEEND];
  636. FogDensity = pContext->fRenderStates[D3DRENDERSTATE_FOGTABLEDENSITY];
  637. DISPDBG((DBGLVL,"FogStart = %d FogEnd = %d FogDensity = %d",
  638. (LONG)(FogStart*1000.0f),
  639. (LONG)(FogEnd*1000.0f),
  640. (LONG)(FogDensity*1000.0f) ));
  641. // Compute the fog tables in order to load the hw fog tables
  642. if (D3DFOG_LINEAR == dwFogTableMode)
  643. {
  644. TableEntry = 0;
  645. zIncrement = 1.0f / 255.0f;
  646. z = 0.0f;
  647. do
  648. {
  649. // Linear fog, so clamp top and bottom
  650. if (z < FogStart)
  651. {
  652. fValue = 1.0f;
  653. }
  654. else if (z > FogEnd)
  655. {
  656. fValue = 0.0f;
  657. }
  658. else
  659. {
  660. // If the end == the start, don't fog
  661. if (FogEnd == FogStart)
  662. {
  663. fValue = 1.0f;
  664. }
  665. else
  666. {
  667. fValue = (FogEnd - z) / (FogEnd - FogStart);
  668. }
  669. ASSERTDD(fValue <= 1.0f,
  670. "Error: Result to big");
  671. ASSERTDD(fValue >= 0.0f,
  672. "Error: Result negative");
  673. }
  674. // Scale the result to fill the
  675. // 8 bit range in the table
  676. fValue = fValue * 255.0f;
  677. fEntry[TableEntry++] = fValue;
  678. z += zIncrement;
  679. } while (TableEntry < 256);
  680. }
  681. else if (D3DFOG_EXP == dwFogTableMode)
  682. {
  683. TableEntry = 0;
  684. zIncrement = 1.0f / 255.0f;
  685. z = 0.0f;
  686. do
  687. {
  688. float fz;
  689. fz = z * FogDensity;
  690. fValue = myPow(math_e, -fz);
  691. if (fValue <= 0.0f) fValue = 0.0f;
  692. if (fValue > 1.0f) fValue = 1.0f;
  693. // Scale the result to fill the
  694. // 8 bit range in the table
  695. fValue = fValue * 255.0f;
  696. DISPDBG((DBGLVL,"Table Entry %d = %f, for Z = %f",
  697. TableEntry, fValue, z));
  698. fEntry[TableEntry++] = fValue;
  699. z += zIncrement;
  700. } while (TableEntry < 256);
  701. }
  702. else // must be if(D3DFOG_EXP2 == dwFogTableMode)
  703. {
  704. TableEntry = 0;
  705. zIncrement = 1.0f / 255.0f;
  706. z = 0.0f;
  707. do
  708. {
  709. float fz;
  710. fz = z * FogDensity;
  711. fValue = myPow(math_e, -(fz * fz));
  712. if (fValue <= 0.0f) fValue = 0.0f;
  713. if (fValue > 1.0f) fValue = 1.0f;
  714. // Scale the result to fill the
  715. // 8 bit range in the table
  716. fValue = fValue * 255.0f;
  717. DISPDBG((DBGLVL,"Table Entry %d = %f, for Z = %f",
  718. TableEntry, fValue, z));
  719. fEntry[TableEntry++] = fValue;
  720. z += zIncrement;
  721. } while (TableEntry < 256);
  722. }
  723. P3_DMA_GET_BUFFER();
  724. lWaitFifoEntries = 2;
  725. // Pack the fog entries into the chip's fog table
  726. CurrentEntry = 0;
  727. for (TableEntry = 0; TableEntry < 256; TableEntry += 4)
  728. {
  729. DWORD Val[4];
  730. DWORD dwValue;
  731. myFtoi((int*)&Val[0], fEntry[TableEntry]);
  732. myFtoi((int*)&Val[1], fEntry[TableEntry + 1]);
  733. myFtoi((int*)&Val[2], fEntry[TableEntry + 2]);
  734. myFtoi((int*)&Val[3], fEntry[TableEntry + 3]);
  735. lWaitFifoEntries -= 2;
  736. if (lWaitFifoEntries < 2)
  737. {
  738. P3_ENSURE_DX_SPACE(32);
  739. WAIT_FIFO(32);
  740. lWaitFifoEntries += 32;
  741. }
  742. dwValue = ((Val[0] ) |
  743. (Val[1] << 8) |
  744. (Val[2] << 16) |
  745. (Val[3] << 24));
  746. SEND_P3_DATA_OFFSET(FogTable0,
  747. dwValue,
  748. CurrentEntry++);
  749. }
  750. P3_DMA_COMMIT_BUFFER();
  751. break;
  752. default:
  753. DISPDBG((ERRLVL,"ERROR: Unknown fog table mode!"));
  754. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  755. break;
  756. } // switch (dwFogTableMode)
  757. } // if (!pContext->RenderStates[D3DRENDERSTATE_FOGENABLE])
  758. P3_DMA_GET_BUFFER_ENTRIES(6);
  759. SEND_P3_DATA(ZFogBias, 0);
  760. COPY_P3_DATA(FogMode, pSoftP3RX->P3RXFogMode);
  761. COPY_P3_DATA(DeltaMode, pSoftP3RX->P3RX_P3DeltaMode);
  762. P3_DMA_COMMIT_BUFFER();
  763. } // if (pContext->dwDirtyFlags & CONTEXT_DIRTY_FOG)
  764. //*********************************************************
  765. // Has any other texture state changed?
  766. //*********************************************************
  767. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_TEXTURE)
  768. {
  769. DISPDBG((DBGLVL," Texture State"));
  770. _D3DChangeTextureP3RX(pContext);
  771. DIRTY_GAMMA_STATE;
  772. }
  773. //*********************************************************
  774. // Has the alphablend type changed?
  775. //*********************************************************
  776. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_ALPHABLEND)
  777. {
  778. // This _must_ be done after where _D3DChangeTextureP3RX is done,
  779. // because it might need to change behaviour depending on
  780. // the D3D pipeline.
  781. P3_DMA_GET_BUFFER_ENTRIES(6);
  782. if (pContext->RenderStates[D3DRENDERSTATE_BLENDENABLE] == FALSE)
  783. {
  784. if ( pContext->bAlphaBlendMustDoubleSourceColour )
  785. {
  786. // We need to double the source colour, even with no other blend.
  787. pSoftP3RX->P3RXAlphaBlendAlphaMode.Enable = __PERMEDIA_DISABLE;
  788. pSoftP3RX->P3RXAlphaBlendColorMode.Enable = __PERMEDIA_ENABLE;
  789. pSoftP3RX->P3RXFBDestReadMode.ReadEnable = __PERMEDIA_DISABLE;
  790. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_ONE;
  791. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_ZERO;
  792. pSoftP3RX->P3RXAlphaBlendColorMode.SourceTimesTwo = __PERMEDIA_ENABLE;
  793. pSoftP3RX->P3RXAlphaBlendColorMode.DestTimesTwo = __PERMEDIA_DISABLE;
  794. }
  795. else
  796. {
  797. pSoftP3RX->P3RXAlphaBlendAlphaMode.Enable = __PERMEDIA_DISABLE;
  798. pSoftP3RX->P3RXAlphaBlendColorMode.Enable = __PERMEDIA_DISABLE;
  799. pSoftP3RX->P3RXFBDestReadMode.ReadEnable = __PERMEDIA_DISABLE;
  800. }
  801. }
  802. else
  803. {
  804. BOOL bSrcUsesDst, bSrcUsesSrc, bDstUsesSrc, bDstUsesDst;
  805. pSoftP3RX->P3RXAlphaBlendAlphaMode.Enable = __PERMEDIA_ENABLE;
  806. pSoftP3RX->P3RXAlphaBlendColorMode.Enable = __PERMEDIA_ENABLE;
  807. if ( pContext->bAlphaBlendMustDoubleSourceColour )
  808. {
  809. pSoftP3RX->P3RXAlphaBlendColorMode.SourceTimesTwo = __PERMEDIA_ENABLE;
  810. }
  811. else
  812. {
  813. pSoftP3RX->P3RXAlphaBlendColorMode.SourceTimesTwo = __PERMEDIA_DISABLE;
  814. }
  815. pSoftP3RX->P3RXAlphaBlendColorMode.DestTimesTwo = __PERMEDIA_DISABLE;
  816. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceTimesTwo = __PERMEDIA_DISABLE;
  817. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestTimesTwo = __PERMEDIA_DISABLE;
  818. // Assumptions. Will be overridden below in certain cases.
  819. // AusesB means that the A blend function uses the B data.
  820. bSrcUsesSrc = TRUE;
  821. bDstUsesSrc = FALSE;
  822. bSrcUsesDst = FALSE;
  823. bDstUsesDst = TRUE;
  824. switch (pContext->RenderStates[D3DRENDERSTATE_SRCBLEND])
  825. {
  826. case D3DBLEND_BOTHSRCALPHA:
  827. bDstUsesSrc = TRUE;
  828. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_SRC_ALPHA;
  829. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  830. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_SRC_ALPHA;
  831. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  832. break;
  833. case D3DBLEND_BOTHINVSRCALPHA:
  834. bDstUsesSrc = TRUE;
  835. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  836. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_SRC_ALPHA;
  837. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  838. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_SRC_ALPHA;
  839. break;
  840. default:
  841. // Not a short-hand blend mode, look at source and dest
  842. switch (pContext->RenderStates[D3DRENDERSTATE_SRCBLEND])
  843. {
  844. case D3DBLEND_ZERO:
  845. bSrcUsesSrc = FALSE;
  846. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_ZERO;
  847. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_ZERO;
  848. break;
  849. case D3DBLEND_SRCCOLOR:
  850. DISPDBG((ERRLVL,"Invalid Source Blend on P3RX D3DBLEND_SRCCOLOR"));
  851. case D3DBLEND_INVSRCCOLOR:
  852. DISPDBG((ERRLVL,"Invalid Source Blend on P3RX D3DBLEND_INVSRCCOLOR"));
  853. //azn SET_BLEND_ERROR ( pContext, BSF_UNSUPPORTED_ALPHA_BLEND );
  854. // fall through
  855. case D3DBLEND_ONE:
  856. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_ONE;
  857. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_ONE;
  858. break;
  859. case D3DBLEND_SRCALPHA:
  860. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_SRC_ALPHA;
  861. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_SRC_ALPHA;
  862. break;
  863. case D3DBLEND_INVSRCALPHA:
  864. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  865. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  866. break;
  867. case D3DBLEND_DESTALPHA:
  868. bSrcUsesDst = TRUE;
  869. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_DST_ALPHA;
  870. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_DST_ALPHA;
  871. break;
  872. case D3DBLEND_INVDESTALPHA:
  873. bSrcUsesDst = TRUE;
  874. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_ONE_MINUS_DST_ALPHA;
  875. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_ONE_MINUS_DST_ALPHA;
  876. break;
  877. case D3DBLEND_DESTCOLOR:
  878. bSrcUsesDst = TRUE;
  879. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_DST_COLOR;
  880. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_DST_COLOR;
  881. break;
  882. case D3DBLEND_INVDESTCOLOR:
  883. bSrcUsesDst = TRUE;
  884. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_ONE_MINUS_DST_COLOR;
  885. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_ONE_MINUS_DST_COLOR;
  886. break;
  887. case D3DBLEND_SRCALPHASAT:
  888. bSrcUsesDst = TRUE;
  889. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = __GLINT_BLEND_FUNC_SRC_ALPHA_SATURATE;
  890. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = __GLINT_BLEND_FUNC_SRC_ALPHA_SATURATE;
  891. break;
  892. default:
  893. DISPDBG((ERRLVL,"Unknown Source Blend on P3RX"));
  894. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_ALPHA_BLEND );
  895. break;
  896. }
  897. switch(pContext->RenderStates[D3DRENDERSTATE_DESTBLEND])
  898. {
  899. case D3DBLEND_ZERO:
  900. bDstUsesDst = FALSE;
  901. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_ZERO;
  902. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_ZERO;
  903. break;
  904. case D3DBLEND_DESTCOLOR:
  905. DISPDBG((ERRLVL,"Invalid Source Blend on P3RX %d D3DBLEND_DESTCOLOR"));
  906. case D3DBLEND_INVDESTCOLOR:
  907. DISPDBG((ERRLVL,"Invalid Source Blend on P3RX %d D3DBLEND_INVDESTCOLOR"));
  908. //azn SET_BLEND_ERROR ( pContext, BSF_UNSUPPORTED_ALPHA_BLEND );
  909. // fall through
  910. case D3DBLEND_ONE:
  911. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_ONE;
  912. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_ONE;
  913. break;
  914. case D3DBLEND_SRCCOLOR:
  915. bDstUsesSrc = TRUE;
  916. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_SRC_COLOR;
  917. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_SRC_COLOR;
  918. if ( pContext->bAlphaBlendMustDoubleSourceColour )
  919. {
  920. // SRCCOLOR needs to be doubled.
  921. pSoftP3RX->P3RXAlphaBlendColorMode.DestTimesTwo = __PERMEDIA_ENABLE;
  922. }
  923. break;
  924. case D3DBLEND_INVSRCCOLOR:
  925. bDstUsesSrc = TRUE;
  926. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_COLOR;
  927. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_COLOR;
  928. if ( pContext->bAlphaBlendMustDoubleSourceColour )
  929. {
  930. // Can't do this. What they want is:
  931. // (1-(srccolor * 2))*destcolor
  932. // = destcolor - 2*srccolor*destcolor
  933. // All we can do is:
  934. // (1-srccolor)*destcolor*2
  935. // = destcolor*2 - 2*srccolor*destcolor
  936. // ...which is a very different thing of course.
  937. // Fail the blend.
  938. SET_BLEND_ERROR ( pContext, BSF_CANT_USE_COLOR_OP_HERE );
  939. }
  940. break;
  941. case D3DBLEND_SRCALPHA:
  942. bDstUsesSrc = TRUE;
  943. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_SRC_ALPHA;
  944. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_SRC_ALPHA;
  945. break;
  946. case D3DBLEND_INVSRCALPHA:
  947. bDstUsesSrc = TRUE;
  948. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  949. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_ONE_MINUS_SRC_ALPHA;
  950. break;
  951. case D3DBLEND_DESTALPHA:
  952. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_DST_ALPHA;
  953. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_DST_ALPHA;
  954. break;
  955. case D3DBLEND_INVDESTALPHA:
  956. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = __GLINT_BLEND_FUNC_ONE_MINUS_DST_ALPHA;
  957. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = __GLINT_BLEND_FUNC_ONE_MINUS_DST_ALPHA;
  958. break;
  959. default:
  960. DISPDBG((ERRLVL,"Unknown Destination Blend on P3RX"));
  961. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  962. break;
  963. }
  964. break;
  965. }
  966. if ( bSrcUsesDst || bDstUsesDst )
  967. {
  968. // Yep, using the destination data.
  969. pSoftP3RX->P3RXFBDestReadMode.ReadEnable = __PERMEDIA_ENABLE;
  970. }
  971. else
  972. {
  973. pSoftP3RX->P3RXFBDestReadMode.ReadEnable = __PERMEDIA_DISABLE;
  974. }
  975. // We need to verify if the blending mode will use the alpha
  976. // channel of the destination fragment (buffer) and if the buffer
  977. // does in fact have an alpha buffer. If not, we need to make sure
  978. // hw will assume this value == 1.0 (0xFF in ARGB).
  979. // The D3DBLEND_SRCALPHASAT blend mode also involves the
  980. // destination alpha
  981. pSoftP3RX->P3RXAlphaBlendAlphaMode.NoAlphaBuffer = __PERMEDIA_DISABLE;
  982. if ((pContext->RenderStates[D3DRENDERSTATE_DESTBLEND] == D3DBLEND_INVDESTALPHA) ||
  983. (pContext->RenderStates[D3DRENDERSTATE_DESTBLEND] == D3DBLEND_DESTALPHA) ||
  984. (pContext->RenderStates[D3DRENDERSTATE_SRCBLEND] == D3DBLEND_INVDESTALPHA) ||
  985. (pContext->RenderStates[D3DRENDERSTATE_SRCBLEND] == D3DBLEND_DESTALPHA) ||
  986. (pContext->RenderStates[D3DRENDERSTATE_SRCBLEND] == D3DBLEND_SRCALPHASAT))
  987. {
  988. if (!pContext->pSurfRenderInt->pFormatSurface->bAlpha)
  989. {
  990. pSoftP3RX->P3RXAlphaBlendAlphaMode.NoAlphaBuffer = __PERMEDIA_ENABLE;
  991. }
  992. }
  993. // We could now check if the src data is ever used. If not, bin
  994. // the whole previous pipeline! But this rarely happens.
  995. // A case where it might is if they are updating just the Z buffer,
  996. // but not changing the picture (e.g. for mirrors or portals).
  997. }
  998. COPY_P3_DATA(AlphaBlendAlphaMode, pSoftP3RX->P3RXAlphaBlendAlphaMode);
  999. COPY_P3_DATA(AlphaBlendColorMode, pSoftP3RX->P3RXAlphaBlendColorMode);
  1000. COPY_P3_DATA(FBDestReadMode, pSoftP3RX->P3RXFBDestReadMode);
  1001. P3_DMA_COMMIT_BUFFER();
  1002. }
  1003. //*********************************************************
  1004. // Have w buffering parameters changed?
  1005. //*********************************************************
  1006. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_WBUFFER)
  1007. {
  1008. float noverf;
  1009. float NF_factor;
  1010. if ( (pContext->RenderStates[D3DRENDERSTATE_ZENABLE] == D3DZB_USEW) &&
  1011. (pContext->pSurfZBufferInt) )
  1012. {
  1013. DISPDBG((DBGLVL,"WBuffer wNear: %f, wFar: %f",
  1014. pContext->WBufferInfo.dvWNear,
  1015. pContext->WBufferInfo.dvWFar));
  1016. noverf = (pContext->WBufferInfo.dvWNear /
  1017. pContext->WBufferInfo.dvWFar);
  1018. NF_factor = (1.0 / 256.0);
  1019. // Compare range in decending order.
  1020. // Note that Exponent Width is determined
  1021. // as DepthMode.ExponentWidth +1
  1022. if (noverf >= (myPow(2,-0) * NF_factor))
  1023. {
  1024. // Use linear Z
  1025. pSoftP3RX->P3RXDepthMode.NonLinearZ = FALSE;
  1026. }
  1027. else if (noverf >= (myPow(2,-1) * NF_factor))
  1028. {
  1029. // Use exp width 1, exp scale 2
  1030. pSoftP3RX->P3RXDepthMode.ExponentWidth = 0;
  1031. pSoftP3RX->P3RXDepthMode.ExponentScale = 2;
  1032. pSoftP3RX->P3RXDepthMode.NonLinearZ = TRUE;
  1033. }
  1034. else if (noverf >= (myPow(2,-3) * NF_factor))
  1035. {
  1036. // Use exp width 2, exp scale 1
  1037. pSoftP3RX->P3RXDepthMode.ExponentWidth = 1;
  1038. pSoftP3RX->P3RXDepthMode.ExponentScale = 1;
  1039. pSoftP3RX->P3RXDepthMode.NonLinearZ = TRUE;
  1040. }
  1041. else if (noverf >= (myPow(2,-4) * NF_factor))
  1042. {
  1043. // Use exp width 2, exp scale 2
  1044. pSoftP3RX->P3RXDepthMode.ExponentWidth = 1;
  1045. pSoftP3RX->P3RXDepthMode.ExponentScale = 2;
  1046. pSoftP3RX->P3RXDepthMode.NonLinearZ = TRUE;
  1047. }
  1048. else if (noverf >= (myPow(2,-7) * NF_factor))
  1049. {
  1050. // Use exp width 3, exp scale 1
  1051. pSoftP3RX->P3RXDepthMode.ExponentWidth = 2;
  1052. pSoftP3RX->P3RXDepthMode.ExponentScale = 1;
  1053. pSoftP3RX->P3RXDepthMode.NonLinearZ = TRUE;
  1054. }
  1055. else
  1056. {
  1057. // Use exp width 3, exp scale 2
  1058. pSoftP3RX->P3RXDepthMode.ExponentWidth = 3;
  1059. pSoftP3RX->P3RXDepthMode.ExponentScale = 2;
  1060. pSoftP3RX->P3RXDepthMode.NonLinearZ = TRUE;
  1061. }
  1062. }
  1063. else
  1064. {
  1065. pSoftP3RX->P3RXDepthMode.NonLinearZ = FALSE;
  1066. }
  1067. P3_DMA_GET_BUFFER_ENTRIES(2);
  1068. COPY_P3_DATA(DepthMode, pSoftP3RX->P3RXDepthMode);
  1069. P3_DMA_COMMIT_BUFFER();
  1070. }
  1071. //*********************************************************
  1072. // Have the rendertarget/ z buffer address changed?
  1073. //*********************************************************
  1074. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_RENDER_OFFSETS)
  1075. {
  1076. DISPDBG((DBGLVL," Render Offsets"));
  1077. _D3D_OP_SetRenderTarget(pContext,
  1078. pContext->pSurfRenderInt,
  1079. pContext->pSurfZBufferInt,
  1080. FALSE);
  1081. P3_DMA_GET_BUFFER_ENTRIES(2);
  1082. COPY_P3_DATA(DeltaControl, pSoftP3RX->P3RX_P3DeltaControl);
  1083. P3_DMA_COMMIT_BUFFER();
  1084. }
  1085. //*********************************************************
  1086. // Have the viewport parameters changed?
  1087. //*********************************************************
  1088. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_VIEWPORT)
  1089. {
  1090. P3_DMA_GET_BUFFER_ENTRIES(12);
  1091. DISPDBG((DBGLVL,"Viewport left: %d, top: %d, width: %d, height: %d",
  1092. pContext->ViewportInfo.dwX,
  1093. pContext->ViewportInfo.dwY,
  1094. pContext->ViewportInfo.dwWidth,
  1095. pContext->ViewportInfo.dwHeight));
  1096. // If a valid viewport is setup, scissor it
  1097. if ((pContext->ViewportInfo.dwWidth != 0) &&
  1098. (pContext->ViewportInfo.dwHeight != 0))
  1099. {
  1100. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  1101. if (pContext->Flags & SURFACE_ANTIALIAS)
  1102. {
  1103. pSoftP3RX->P3RXScissorMinXY.X = pContext->ViewportInfo.dwX * 2;
  1104. pSoftP3RX->P3RXScissorMinXY.Y = pContext->ViewportInfo.dwY * 2;
  1105. pSoftP3RX->P3RXScissorMaxXY.X = (pContext->ViewportInfo.dwWidth * 2) +
  1106. pContext->ViewportInfo.dwX;
  1107. pSoftP3RX->P3RXScissorMaxXY.Y = (pContext->ViewportInfo.dwHeight * 2) +
  1108. pContext->ViewportInfo.dwY;
  1109. }
  1110. else
  1111. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  1112. {
  1113. pSoftP3RX->P3RXScissorMinXY.X = pContext->ViewportInfo.dwX;
  1114. pSoftP3RX->P3RXScissorMinXY.Y = pContext->ViewportInfo.dwY;
  1115. pSoftP3RX->P3RXScissorMaxXY.X = pContext->ViewportInfo.dwWidth +
  1116. pContext->ViewportInfo.dwX;
  1117. pSoftP3RX->P3RXScissorMaxXY.Y = pContext->ViewportInfo.dwHeight +
  1118. pContext->ViewportInfo.dwY;
  1119. }
  1120. COPY_P3_DATA(ScissorMinXY, pSoftP3RX->P3RXScissorMinXY);
  1121. COPY_P3_DATA(ScissorMaxXY, pSoftP3RX->P3RXScissorMaxXY);
  1122. SEND_P3_DATA(YLimits, (pContext->ViewportInfo.dwY & 0xFFFF) |
  1123. (pSoftP3RX->P3RXScissorMaxXY.Y << 16));
  1124. SEND_P3_DATA(XLimits, (pContext->ViewportInfo.dwX & 0xFFFF) |
  1125. (pSoftP3RX->P3RXScissorMaxXY.X << 16));
  1126. // Enable user scissor
  1127. SEND_P3_DATA(ScissorMode, 1);
  1128. pSoftP3RX->P3RXRasterizerMode.YLimitsEnable = __PERMEDIA_ENABLE;
  1129. COPY_P3_DATA(RasterizerMode, pSoftP3RX->P3RXRasterizerMode);
  1130. }
  1131. else
  1132. {
  1133. SEND_P3_DATA(ScissorMode, 0);
  1134. pSoftP3RX->P3RXRasterizerMode.YLimitsEnable = __PERMEDIA_DISABLE;
  1135. COPY_P3_DATA(RasterizerMode, pSoftP3RX->P3RXRasterizerMode);
  1136. }
  1137. P3_DMA_COMMIT_BUFFER();
  1138. }
  1139. //*********************************************************
  1140. // Can we optimize the pipeline? (Depends on misc. RS)
  1141. //*********************************************************
  1142. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_PIPELINEORDER)
  1143. {
  1144. // Must switch over the router mode if we are testing and expect
  1145. // the Z to be discarded.
  1146. P3_DMA_GET_BUFFER_ENTRIES(2);
  1147. DISPDBG((DBGLVL, " Pipeline order"));
  1148. if (((pContext->RenderStates[D3DRENDERSTATE_ALPHATESTENABLE]) ||
  1149. (pContext->RenderStates[D3DRENDERSTATE_COLORKEYENABLE])) &&
  1150. (pContext->RenderStates[D3DRENDERSTATE_ZWRITEENABLE]))
  1151. {
  1152. SEND_P3_DATA(RouterMode, __PERMEDIA_DISABLE);
  1153. }
  1154. else
  1155. {
  1156. SEND_P3_DATA(RouterMode, __PERMEDIA_ENABLE);
  1157. }
  1158. P3_DMA_COMMIT_BUFFER();
  1159. }
  1160. //*********************************************************
  1161. // Can we optimize the alpha pipeline? (Depends on misc. RS)
  1162. //*********************************************************
  1163. // DO AT THE END
  1164. //*********************************************************
  1165. if (pContext->dwDirtyFlags & CONTEXT_DIRTY_OPTIMIZE_ALPHA)
  1166. {
  1167. P3_DMA_GET_BUFFER_ENTRIES(6);
  1168. DISPDBG((DBGLVL, " Alpha optimizations"));
  1169. pSoftP3RX->P3RXFBDestReadMode.AlphaFiltering = __PERMEDIA_DISABLE;
  1170. // There may be an optimization when blending is on
  1171. if (pContext->RenderStates[D3DRENDERSTATE_BLENDENABLE])
  1172. {
  1173. // Check the RouterMode path
  1174. if (((pContext->RenderStates[D3DRENDERSTATE_ALPHATESTENABLE]) ||
  1175. (pContext->RenderStates[D3DRENDERSTATE_COLORKEYENABLE])) &&
  1176. (pContext->RenderStates[D3DRENDERSTATE_ZWRITEENABLE]))
  1177. {
  1178. // Slow mode
  1179. }
  1180. else
  1181. {
  1182. // Fast mode. The Z value will be written before the alpha test. This means that we
  1183. // can use the alpha test to discard pixels if it is not already in use.
  1184. if (!(pContext->RenderStates[D3DRENDERSTATE_ALPHATESTENABLE]) &&
  1185. !(pContext->RenderStates[D3DRENDERSTATE_COLORKEYENABLE]))
  1186. {
  1187. // Check for known blends.
  1188. if ((pContext->RenderStates[D3DRENDERSTATE_SRCBLEND] == D3DBLEND_BOTHSRCALPHA) ||
  1189. ((pContext->RenderStates[D3DRENDERSTATE_SRCBLEND] == D3DBLEND_SRCALPHA) &&
  1190. (pContext->RenderStates[D3DRENDERSTATE_DESTBLEND] == D3DBLEND_INVSRCALPHA)))
  1191. {
  1192. // SRCALPHA:INVSRCALPH
  1193. pSoftP3RX->P3RXAlphaTestMode.Reference = 0;
  1194. pSoftP3RX->P3RXAlphaTestMode.Enable = __PERMEDIA_ENABLE;
  1195. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_GREATER;
  1196. pSoftP3RX->P3RXFBDestReadMode.AlphaFiltering = __PERMEDIA_ENABLE;
  1197. pSoftP3RX->P3RXFBDestReadEnables.ReferenceAlpha = 0xFF;
  1198. }
  1199. }
  1200. }
  1201. }
  1202. COPY_P3_DATA(FBDestReadEnables, pSoftP3RX->P3RXFBDestReadEnables);
  1203. COPY_P3_DATA(FBDestReadMode, pSoftP3RX->P3RXFBDestReadMode);
  1204. COPY_P3_DATA(AlphaTestMode, pSoftP3RX->P3RXAlphaTestMode);
  1205. P3_DMA_COMMIT_BUFFER();
  1206. }
  1207. } // __ST_HandleDirtyP3State
  1208. //-----------------------------------------------------------------------------
  1209. //
  1210. // _D3D_ST_ProcessOneRenderState
  1211. //
  1212. //-----------------------------------------------------------------------------
  1213. #define NOT_HANDLED DISPDBG((DBGLVL, " **Not Currently Handled**"));
  1214. DWORD
  1215. _D3D_ST_ProcessOneRenderState(
  1216. P3_D3DCONTEXT* pContext,
  1217. DWORD dwRSType,
  1218. DWORD dwRSVal)
  1219. {
  1220. P3_SOFTWARECOPY* pSoftP3RX;
  1221. P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
  1222. DWORD *pFlags;
  1223. DWORD *pdwTextureStageState_0, *pdwTextureStageState_1;
  1224. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  1225. BOOL bDX7_Antialiasing = FALSE;
  1226. #endif // DX8_MULTISAMPLING || DX7_ANTIALIASING
  1227. P3_DMA_DEFS();
  1228. DBG_ENTRY(_D3D_ST_ProcessOneRenderState);
  1229. pSoftP3RX = &pContext->SoftCopyGlint;
  1230. DISPDBG((DBGLVL, "_D3D_ST_ProcessOneRenderState: dwType =%08lx, dwVal=%d",
  1231. dwRSType, dwRSVal));
  1232. if (dwRSType >= D3DHAL_MAX_RSTATES)
  1233. {
  1234. DISPDBG((WRNLVL, "_D3D_ST_ProcessOneRenderState: OUT OF RANGE"
  1235. " dwType =%08lx, dwVal=%d", dwRSType, dwRSVal));
  1236. return DD_OK;
  1237. }
  1238. // Store the state in the context
  1239. pContext->RenderStates[dwRSType] = dwRSVal;
  1240. // Prepare pointer to the contexts state flags for updates
  1241. pFlags = &pContext->Flags;
  1242. // Prepare pointers to the stored TSS in case we need them
  1243. pdwTextureStageState_0 =
  1244. &(pContext->TextureStageState[TEXSTAGE_0].m_dwVal[0]);
  1245. pdwTextureStageState_1 =
  1246. &(pContext->TextureStageState[TEXSTAGE_1].m_dwVal[0]);
  1247. // Prepare DMA Buffer for 8 entries in case we need to add to it
  1248. P3_DMA_GET_BUFFER();
  1249. P3_ENSURE_DX_SPACE(8);
  1250. WAIT_FIFO(8);
  1251. // Process according to the type of renderstate. For multivalued
  1252. // renderstates do some kind of value checking and make sure to
  1253. // setup valid defaults where needed.
  1254. switch (dwRSType)
  1255. {
  1256. //----------------------------------------------------------------------
  1257. //----------------------------------------------------------------------
  1258. // The following are D3D renderstates which are still in use by DX8 Apps
  1259. //----------------------------------------------------------------------
  1260. //----------------------------------------------------------------------
  1261. case D3DRENDERSTATE_ZENABLE:
  1262. DISPDBG((DBGLVL, "SET D3DRS_ZENABLE = 0x%x",dwRSVal));
  1263. DIRTY_ZBUFFER(pContext);
  1264. break;
  1265. case D3DRENDERSTATE_FILLMODE:
  1266. DISPDBG((DBGLVL, "SET D3DRS_FILLMODE = 0x%x",dwRSVal));
  1267. switch (dwRSVal)
  1268. {
  1269. case D3DFILL_POINT:
  1270. case D3DFILL_WIREFRAME:
  1271. case D3DFILL_SOLID:
  1272. // These values are OK
  1273. break;
  1274. default:
  1275. // We've received an illegal value, default to solid fills...
  1276. DISPDBG((ERRLVL,"_D3D_ST_ProcessOneRenderState: "
  1277. "unknown FILLMODE value"));
  1278. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  1279. pContext->RenderStates[D3DRENDERSTATE_FILLMODE] =
  1280. D3DFILL_SOLID;
  1281. break;
  1282. }
  1283. break;
  1284. case D3DRENDERSTATE_SHADEMODE:
  1285. DISPDBG((DBGLVL, "SET D3DRS_SHADEMODE = 0x%x",dwRSVal));
  1286. switch(dwRSVal)
  1287. {
  1288. case D3DSHADE_PHONG:
  1289. // Can't actually do Phong, but everyone knows this and
  1290. // assumes we use Gouraud instead.
  1291. SET_BLEND_ERROR ( pContext, BS_PHONG_SHADING );
  1292. // fall through and setup Gouraud instead
  1293. case D3DSHADE_GOURAUD:
  1294. pSoftP3RX->ColorDDAMode.UnitEnable = 1;
  1295. pSoftP3RX->ColorDDAMode.ShadeMode = 1;
  1296. COPY_P3_DATA(ColorDDAMode, pSoftP3RX->ColorDDAMode);
  1297. pSoftP3RX->P3RX_P3DeltaMode.SmoothShadingEnable = 1;
  1298. pSoftP3RX->P3RX_P3DeltaControl.UseProvokingVertex = 0;
  1299. pSoftP3RX->P3RX_P3VertexControl.Flat = 0;
  1300. COPY_P3_DATA(DeltaMode, pSoftP3RX->P3RX_P3DeltaMode);
  1301. COPY_P3_DATA(DeltaControl, pSoftP3RX->P3RX_P3DeltaControl);
  1302. COPY_P3_DATA(VertexControl, pSoftP3RX->P3RX_P3VertexControl);
  1303. *pFlags |= SURFACE_GOURAUD;
  1304. // If we are texturing, some changes may need to be made
  1305. if (pdwTextureStageState_0[D3DTSS_TEXTUREMAP] != 0)
  1306. {
  1307. DIRTY_TEXTURE(pContext);
  1308. }
  1309. break;
  1310. case D3DSHADE_FLAT:
  1311. pSoftP3RX->ColorDDAMode.UnitEnable = 1;
  1312. pSoftP3RX->ColorDDAMode.ShadeMode = 0;
  1313. COPY_P3_DATA(ColorDDAMode, pSoftP3RX->ColorDDAMode);
  1314. pSoftP3RX->P3RX_P3DeltaMode.SmoothShadingEnable = 0;
  1315. pSoftP3RX->P3RX_P3DeltaControl.UseProvokingVertex = 1;
  1316. pSoftP3RX->P3RX_P3VertexControl.Flat = 1;
  1317. COPY_P3_DATA(DeltaMode, pSoftP3RX->P3RX_P3DeltaMode);
  1318. COPY_P3_DATA(DeltaControl, pSoftP3RX->P3RX_P3DeltaControl);
  1319. COPY_P3_DATA(VertexControl, pSoftP3RX->P3RX_P3VertexControl);
  1320. *pFlags &= ~SURFACE_GOURAUD;
  1321. // If we are texturing, some changes may need to be made
  1322. if (pdwTextureStageState_0[D3DTSS_TEXTUREMAP] != 0)
  1323. {
  1324. DIRTY_TEXTURE(pContext);
  1325. }
  1326. break;
  1327. default:
  1328. DISPDBG((ERRLVL,"_D3D_ST_ProcessOneRenderState: "
  1329. "unknown SHADEMODE value"));
  1330. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  1331. break;
  1332. }
  1333. break;
  1334. case D3DRENDERSTATE_LINEPATTERN:
  1335. DISPDBG((DBGLVL, "SET D3DRS_LINEPATTERN = 0x%x",dwRSVal));
  1336. if (dwRSVal == 0)
  1337. {
  1338. pSoftP3RX->PXRXLineStippleMode.StippleEnable = __PERMEDIA_DISABLE;
  1339. RENDER_LINE_STIPPLE_DISABLE(pContext->RenderCommand);
  1340. }
  1341. else
  1342. {
  1343. pSoftP3RX->PXRXLineStippleMode.StippleEnable = __PERMEDIA_ENABLE;
  1344. pSoftP3RX->PXRXLineStippleMode.RepeatFactor =
  1345. (dwRSVal & 0x0000FFFF) -1 ;
  1346. pSoftP3RX->PXRXLineStippleMode.StippleMask =
  1347. (dwRSVal & 0xFFFF0000) >> 16;
  1348. pSoftP3RX->PXRXLineStippleMode.Mirror = __PERMEDIA_DISABLE;
  1349. RENDER_LINE_STIPPLE_ENABLE(pContext->RenderCommand);
  1350. }
  1351. COPY_P3_DATA( LineStippleMode, pSoftP3RX->PXRXLineStippleMode);
  1352. break;
  1353. case D3DRENDERSTATE_ZWRITEENABLE:
  1354. DISPDBG((DBGLVL, "SET D3DRS_ZWRITEENABLE = 0x%x",dwRSVal));
  1355. if (dwRSVal != 0)
  1356. {
  1357. // Local Buffer Write mode
  1358. if(!(*pFlags & SURFACE_ZWRITEENABLE))
  1359. {
  1360. DISPDBG((DBGLVL, "Enabling Z Writes"));
  1361. *pFlags |= SURFACE_ZWRITEENABLE;
  1362. DIRTY_ZBUFFER(pContext);
  1363. DIRTY_PIPELINEORDER(pContext);
  1364. DIRTY_OPTIMIZE_ALPHA(pContext);
  1365. }
  1366. }
  1367. else
  1368. {
  1369. if (*pFlags & SURFACE_ZWRITEENABLE)
  1370. {
  1371. DISPDBG((DBGLVL, "Disabling Z Writes"));
  1372. *pFlags &= ~SURFACE_ZWRITEENABLE;
  1373. DIRTY_ZBUFFER(pContext);
  1374. DIRTY_PIPELINEORDER(pContext);
  1375. DIRTY_OPTIMIZE_ALPHA(pContext);
  1376. }
  1377. }
  1378. break;
  1379. case D3DRENDERSTATE_ALPHATESTENABLE:
  1380. DISPDBG((DBGLVL, "SET D3DRS_ALPHATESTENABLE = 0x%x",dwRSVal));
  1381. DIRTY_ALPHATEST(pContext);
  1382. DIRTY_PIPELINEORDER(pContext);
  1383. DIRTY_OPTIMIZE_ALPHA(pContext);
  1384. break;
  1385. case D3DRENDERSTATE_LASTPIXEL:
  1386. DISPDBG((DBGLVL, "SET D3DRS_LASTPIXEL = 0x%x",dwRSVal));
  1387. NOT_HANDLED;
  1388. break;
  1389. case D3DRENDERSTATE_SRCBLEND:
  1390. DISPDBG((DBGLVL, "SET D3DRS_SRCBLEND = 0x%x",dwRSVal));
  1391. DIRTY_ALPHABLEND(pContext);
  1392. DIRTY_OPTIMIZE_ALPHA(pContext);
  1393. break;
  1394. case D3DRENDERSTATE_DESTBLEND:
  1395. DISPDBG((DBGLVL, "SET D3DRS_DESTBLEND = 0x%x",dwRSVal));
  1396. DIRTY_ALPHABLEND(pContext);
  1397. DIRTY_OPTIMIZE_ALPHA(pContext);
  1398. break;
  1399. case D3DRENDERSTATE_CULLMODE:
  1400. DISPDBG((DBGLVL, "SET D3DRS_CULLMODE = 0x%x",dwRSVal));
  1401. switch(dwRSVal)
  1402. {
  1403. case D3DCULL_NONE:
  1404. SET_CULLING_TO_NONE(pContext);
  1405. pSoftP3RX->P3RX_P3DeltaMode.BackfaceCull = 0;
  1406. break;
  1407. case D3DCULL_CCW:
  1408. SET_CULLING_TO_CCW(pContext);
  1409. pSoftP3RX->P3RX_P3DeltaMode.BackfaceCull = 0;
  1410. break;
  1411. case D3DCULL_CW:
  1412. SET_CULLING_TO_CW(pContext);
  1413. pSoftP3RX->P3RX_P3DeltaMode.BackfaceCull = 0;
  1414. break;
  1415. default:
  1416. DISPDBG((ERRLVL,"_D3D_ST_ProcessOneRenderState: "
  1417. "unknown cull mode"));
  1418. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  1419. break;
  1420. }
  1421. COPY_P3_DATA(DeltaMode, pSoftP3RX->P3RX_P3DeltaMode);
  1422. break;
  1423. case D3DRENDERSTATE_ZFUNC:
  1424. DISPDBG((DBGLVL, "SET D3DRS_ZFUNC = 0x%x",dwRSVal));
  1425. switch (dwRSVal)
  1426. {
  1427. case D3DCMP_NEVER:
  1428. pSoftP3RX->P3RXDepthMode.CompareMode =
  1429. __GLINT_DEPTH_COMPARE_MODE_NEVER;
  1430. break;
  1431. case D3DCMP_LESS:
  1432. pSoftP3RX->P3RXDepthMode.CompareMode =
  1433. __GLINT_DEPTH_COMPARE_MODE_LESS;
  1434. break;
  1435. case D3DCMP_EQUAL:
  1436. pSoftP3RX->P3RXDepthMode.CompareMode =
  1437. __GLINT_DEPTH_COMPARE_MODE_EQUAL;
  1438. break;
  1439. case D3DCMP_LESSEQUAL:
  1440. pSoftP3RX->P3RXDepthMode.CompareMode =
  1441. __GLINT_DEPTH_COMPARE_MODE_LESS_OR_EQUAL;
  1442. break;
  1443. case D3DCMP_GREATER:
  1444. pSoftP3RX->P3RXDepthMode.CompareMode =
  1445. __GLINT_DEPTH_COMPARE_MODE_GREATER;
  1446. break;
  1447. case D3DCMP_NOTEQUAL:
  1448. pSoftP3RX->P3RXDepthMode.CompareMode =
  1449. __GLINT_DEPTH_COMPARE_MODE_NOT_EQUAL;
  1450. break;
  1451. case D3DCMP_GREATEREQUAL:
  1452. pSoftP3RX->P3RXDepthMode.CompareMode =
  1453. __GLINT_DEPTH_COMPARE_MODE_GREATER_OR_EQUAL;
  1454. break;
  1455. case D3DCMP_ALWAYS:
  1456. pSoftP3RX->P3RXDepthMode.CompareMode =
  1457. __GLINT_DEPTH_COMPARE_MODE_ALWAYS;
  1458. break;
  1459. default:
  1460. DISPDBG((ERRLVL,"_D3D_ST_ProcessOneRenderState: "
  1461. "unknown ZFUNC mode"));
  1462. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  1463. // Set Less or equal as default
  1464. pSoftP3RX->P3RXDepthMode.CompareMode =
  1465. __GLINT_DEPTH_COMPARE_MODE_LESS_OR_EQUAL;
  1466. break;
  1467. }
  1468. DIRTY_ZBUFFER(pContext);
  1469. break;
  1470. case D3DRENDERSTATE_ALPHAREF:
  1471. DISPDBG((DBGLVL, "SET D3DRS_ALPHAREF = 0x%x",dwRSVal));
  1472. DIRTY_ALPHATEST(pContext);
  1473. break;
  1474. case D3DRENDERSTATE_ALPHAFUNC:
  1475. DISPDBG((DBGLVL, "SET D3DRS_ALPHAFUNC = 0x%x",dwRSVal));
  1476. DIRTY_ALPHATEST(pContext);
  1477. break;
  1478. case D3DRENDERSTATE_DITHERENABLE:
  1479. DISPDBG((DBGLVL, "SET D3DRS_DITHERENABLE = 0x%x",dwRSVal));
  1480. if (dwRSVal != 0)
  1481. {
  1482. pSoftP3RX->DitherMode.DitherEnable = __PERMEDIA_ENABLE;
  1483. }
  1484. else
  1485. {
  1486. pSoftP3RX->DitherMode.DitherEnable = __PERMEDIA_DISABLE;
  1487. }
  1488. COPY_P3_DATA(DitherMode, pSoftP3RX->DitherMode);
  1489. break;
  1490. case D3DRENDERSTATE_BLENDENABLE:
  1491. DISPDBG((DBGLVL, "SET D3DRS_BLENDENABLE = 0x%x",dwRSVal));
  1492. // Although render states whose values are boolean in type are
  1493. // documented as only accepting TRUE(1) and FALSE(0) the runtime
  1494. // does not validate this and accepts any non-zero value as true.
  1495. // The sample driver interprets this strictly and does interpret
  1496. // values other than 1 as being TRUE. However, as the runtime
  1497. // does not offer validation your driver should interpret 0 as
  1498. // FALSE and any other non-zero value as TRUE.
  1499. if (dwRSVal != 0)
  1500. {
  1501. if(!(*pFlags & SURFACE_ALPHAENABLE))
  1502. {
  1503. // Set the blend enable flag in the render context struct
  1504. *pFlags |= SURFACE_ALPHAENABLE;
  1505. DIRTY_ALPHABLEND(pContext);
  1506. DIRTY_OPTIMIZE_ALPHA(pContext);
  1507. }
  1508. }
  1509. else
  1510. {
  1511. if (*pFlags & SURFACE_ALPHAENABLE)
  1512. {
  1513. // Turn off blend enable flag in render context struct
  1514. *pFlags &= ~SURFACE_ALPHAENABLE;
  1515. DIRTY_ALPHABLEND(pContext);
  1516. DIRTY_OPTIMIZE_ALPHA(pContext);
  1517. }
  1518. }
  1519. break;
  1520. case D3DRENDERSTATE_FOGENABLE:
  1521. DISPDBG((DBGLVL, "SET D3DRS_FOGENABLE = 0x%x",dwRSVal));
  1522. DIRTY_FOG(pContext);
  1523. break;
  1524. case D3DRENDERSTATE_SPECULARENABLE:
  1525. DISPDBG((DBGLVL, "SET D3DRS_SPECULARENABLE = 0x%x",dwRSVal));
  1526. if (dwRSVal)
  1527. {
  1528. *pFlags |= SURFACE_SPECULAR;
  1529. pSoftP3RX->P3RXTextureApplicationMode.EnableKs = __PERMEDIA_ENABLE;
  1530. pSoftP3RX->P3RX_P3DeltaMode.SpecularTextureEnable = 1;
  1531. }
  1532. else
  1533. {
  1534. *pFlags &= ~SURFACE_SPECULAR;
  1535. pSoftP3RX->P3RXTextureApplicationMode.EnableKs = __PERMEDIA_DISABLE;
  1536. pSoftP3RX->P3RX_P3DeltaMode.SpecularTextureEnable = 0;
  1537. }
  1538. DIRTY_TEXTURE(pContext);
  1539. break;
  1540. case D3DRENDERSTATE_ZVISIBLE:
  1541. DISPDBG((DBGLVL, "SET D3DRS_ZVISIBLE = %d", dwRSVal));
  1542. if (dwRSVal)
  1543. {
  1544. DISPDBG((ERRLVL,"_D3D_ST_ProcessOneRenderState:"
  1545. " ZVISIBLE enabled - no longer supported."));
  1546. }
  1547. break;
  1548. case D3DRENDERSTATE_STIPPLEDALPHA:
  1549. DISPDBG((DBGLVL, "SET D3DRS_STIPPLEDALPHA = 0x%x",dwRSVal));
  1550. if(dwRSVal)
  1551. {
  1552. if (!(*pFlags & SURFACE_ALPHASTIPPLE))
  1553. {
  1554. *pFlags |= SURFACE_ALPHASTIPPLE;
  1555. if (pContext->bKeptStipple)
  1556. {
  1557. RENDER_AREA_STIPPLE_DISABLE(pContext->RenderCommand);
  1558. }
  1559. }
  1560. }
  1561. else
  1562. {
  1563. if (*pFlags & SURFACE_ALPHASTIPPLE)
  1564. {
  1565. // If Alpha Stipple is being turned off, turn the normal
  1566. // stipple back on, and enable it.
  1567. int i;
  1568. for (i = 0; i < 32; i++)
  1569. {
  1570. P3_ENSURE_DX_SPACE(2);
  1571. WAIT_FIFO(2);
  1572. SEND_P3_DATA_OFFSET(AreaStipplePattern0,
  1573. (DWORD)pContext->CurrentStipple[i], i);
  1574. }
  1575. *pFlags &= ~SURFACE_ALPHASTIPPLE;
  1576. if (pContext->bKeptStipple)
  1577. {
  1578. RENDER_AREA_STIPPLE_ENABLE(pContext->RenderCommand);
  1579. }
  1580. }
  1581. }
  1582. break;
  1583. case D3DRENDERSTATE_FOGCOLOR:
  1584. DISPDBG((DBGLVL, "SET D3DRS_FOGCOLOR = 0x%x",dwRSVal));
  1585. DIRTY_FOG(pContext);
  1586. break;
  1587. case D3DRENDERSTATE_FOGTABLEMODE:
  1588. DISPDBG((DBGLVL, "SET D3DRS_FOGTABLEMODE = 0x%x", dwRSVal));
  1589. DIRTY_FOG(pContext);
  1590. break;
  1591. case D3DRENDERSTATE_FOGTABLESTART:
  1592. DISPDBG((DBGLVL, "SET D3DRS_FOGTABLESTART = 0x%x",dwRSVal));
  1593. DIRTY_FOG(pContext);
  1594. break;
  1595. case D3DRENDERSTATE_FOGTABLEEND:
  1596. DISPDBG((DBGLVL, "SET D3DRS_FOGTABLEEND = 0x%x",dwRSVal));
  1597. DIRTY_FOG(pContext);
  1598. break;
  1599. case D3DRENDERSTATE_FOGTABLEDENSITY:
  1600. DISPDBG((DBGLVL, "SET D3DRS_FOGTABLEDENSITY = 0x%x",dwRSVal));
  1601. DIRTY_FOG(pContext);
  1602. break;
  1603. case D3DRENDERSTATE_EDGEANTIALIAS:
  1604. DISPDBG((DBGLVL, "SET D3DRS_EDGEANTIALIAS = 0x%x",dwRSVal));
  1605. NOT_HANDLED;
  1606. break;
  1607. case D3DRENDERSTATE_ZBIAS:
  1608. DISPDBG((DBGLVL, "SET D3DRS_ZBIAS = 0x%x",dwRSVal));
  1609. NOT_HANDLED;
  1610. break;
  1611. case D3DRENDERSTATE_RANGEFOGENABLE:
  1612. DISPDBG((DBGLVL, "SET D3DRS_RANGEFOGENABLE = 0x%x",dwRSVal));
  1613. NOT_HANDLED;
  1614. break;
  1615. case D3DRENDERSTATE_STENCILENABLE:
  1616. DISPDBG((DBGLVL, "SET D3DRS_STENCILENABLE = 0x%x", dwRSVal));
  1617. DIRTY_STENCIL(pContext);
  1618. break;
  1619. case D3DRENDERSTATE_STENCILFAIL:
  1620. DISPDBG((DBGLVL, "SET D3DRS_STENCILFAIL = 0x%x", dwRSVal));
  1621. DIRTY_STENCIL(pContext);
  1622. break;
  1623. case D3DRENDERSTATE_STENCILZFAIL:
  1624. DISPDBG((DBGLVL, "SET D3DRS_STENCILZFAIL = 0x%x", dwRSVal));
  1625. DIRTY_STENCIL(pContext);
  1626. break;
  1627. case D3DRENDERSTATE_STENCILPASS:
  1628. DISPDBG((DBGLVL, "SET D3DRS_STENCILPASS = 0x%x", dwRSVal));
  1629. DIRTY_STENCIL(pContext);
  1630. break;
  1631. case D3DRENDERSTATE_STENCILFUNC:
  1632. DISPDBG((DBGLVL, "SET D3DRS_STENCILFUNC = 0x%x", dwRSVal));
  1633. DIRTY_STENCIL(pContext);
  1634. break;
  1635. case D3DRENDERSTATE_STENCILREF:
  1636. DISPDBG((DBGLVL, "SET D3DRS_STENCILREF = 0x%x", dwRSVal));
  1637. DIRTY_STENCIL(pContext);
  1638. break;
  1639. case D3DRENDERSTATE_STENCILMASK:
  1640. DISPDBG((DBGLVL, "SET D3DRS_STENCILMASK = 0x%x", dwRSVal));
  1641. DIRTY_STENCIL(pContext);
  1642. break;
  1643. case D3DRENDERSTATE_STENCILWRITEMASK:
  1644. DISPDBG((DBGLVL, "SET D3DRS_STENCILENABLE = 0x%x", dwRSVal));
  1645. DIRTY_STENCIL(pContext);
  1646. break;
  1647. case D3DRENDERSTATE_TEXTUREFACTOR:
  1648. // Should not need to dirty anything. This is a good thing -
  1649. // this may be changed frequently in between calls, and may be
  1650. // the only thing to change. Used for some of the odder blend modes.
  1651. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREFACTOR = 0x%x", dwRSVal));
  1652. SEND_P3_DATA ( TextureEnvColor, FORMAT_8888_32BIT_BGR(dwRSVal) );
  1653. SEND_P3_DATA ( TextureCompositeFactor0, FORMAT_8888_32BIT_BGR(dwRSVal) );
  1654. SEND_P3_DATA ( TextureCompositeFactor1, FORMAT_8888_32BIT_BGR(dwRSVal) );
  1655. break;
  1656. case D3DRENDERSTATE_WRAP0:
  1657. case D3DRENDERSTATE_WRAP1:
  1658. case D3DRENDERSTATE_WRAP2:
  1659. case D3DRENDERSTATE_WRAP3:
  1660. case D3DRENDERSTATE_WRAP4:
  1661. case D3DRENDERSTATE_WRAP5:
  1662. case D3DRENDERSTATE_WRAP6:
  1663. case D3DRENDERSTATE_WRAP7:
  1664. DISPDBG((DBGLVL, "SET D3DRS_WRAP %d = 0x%x",
  1665. dwRSType - D3DRENDERSTATE_WRAP0, (DWORD)dwRSVal));
  1666. DIRTY_TEXTURE(pContext);
  1667. break;
  1668. case D3DRENDERSTATE_LOCALVIEWER:
  1669. DISPDBG((DBGLVL, "SET D3DRS_LOCALVIEWER = %d", dwRSVal));
  1670. DIRTY_GAMMA_STATE;
  1671. break;
  1672. case D3DRENDERSTATE_CLIPPING:
  1673. DISPDBG((DBGLVL, "SET D3DRS_CLIPPING = %d", dwRSVal));
  1674. DIRTY_GAMMA_STATE;
  1675. break;
  1676. case D3DRENDERSTATE_LIGHTING:
  1677. DISPDBG((DBGLVL, "SET D3DRS_LIGHTING = %d", dwRSVal));
  1678. DIRTY_GAMMA_STATE;
  1679. break;
  1680. case D3DRENDERSTATE_AMBIENT:
  1681. DISPDBG((DBGLVL, "SET D3DRS_AMBIENT = 0x%x", dwRSVal));
  1682. DIRTY_GAMMA_STATE;
  1683. break;
  1684. //----------------------------------------------------------------------
  1685. //----------------------------------------------------------------------
  1686. // The following are internal D3D renderstates which are created by
  1687. // the runtime. Apps don't send them.
  1688. //----------------------------------------------------------------------
  1689. //----------------------------------------------------------------------
  1690. case D3DRENDERSTATE_SCENECAPTURE:
  1691. DISPDBG((DBGLVL, "SET D3DRS_SCENECAPTURE = 0x%x", dwRSVal));
  1692. {
  1693. DWORD dwFlag;
  1694. if (dwRSVal)
  1695. {
  1696. dwFlag = D3DHAL_SCENE_CAPTURE_START;
  1697. }
  1698. else
  1699. {
  1700. dwFlag = D3DHAL_SCENE_CAPTURE_END;
  1701. }
  1702. #if DX7_TEXMANAGEMENT
  1703. if (dwRSVal)
  1704. {
  1705. // Reset Texture Management counters for next frame
  1706. _D3D_TM_STAT_ResetCounters(pContext);
  1707. }
  1708. #endif // DX7_TEXMANAGEMENT
  1709. // Flush all DMA ops before going to next frame
  1710. P3_DMA_COMMIT_BUFFER();
  1711. _D3D_OP_SceneCapture(pContext, dwFlag);
  1712. // Restart DMA ops
  1713. P3_DMA_GET_BUFFER();
  1714. }
  1715. break;
  1716. #if DX7_TEXMANAGEMENT
  1717. case D3DRENDERSTATE_EVICTMANAGEDTEXTURES:
  1718. DISPDBG((DBGLVL, "SET D3DRENDERSTATE_EVICTMANAGEDTEXTURES = 0x%x",
  1719. dwRSVal));
  1720. if (NULL != pContext->pTextureManager)
  1721. {
  1722. _D3D_TM_EvictAllManagedTextures(pContext);
  1723. }
  1724. break;
  1725. #endif // DX7_TEXMANAGEMENT
  1726. //----------------------------------------------------------------------
  1727. //----------------------------------------------------------------------
  1728. // The following are new DX8 renderstates which we need to process
  1729. // correctly in order to run DX8 apps
  1730. //----------------------------------------------------------------------
  1731. //----------------------------------------------------------------------
  1732. #if DX8_POINTSPRITES
  1733. // Pointsprite support
  1734. case D3DRS_POINTSIZE:
  1735. DISPDBG((DBGLVL, "SET D3DRS_POINTSIZE = 0x%x",dwRSVal));
  1736. *(DWORD*)(&pContext->PntSprite.fSize) = dwRSVal;
  1737. break;
  1738. case D3DRS_POINTSPRITEENABLE:
  1739. DISPDBG((DBGLVL, "SET D3DRS_POINTSPRITEENABLE = 0x%x",dwRSVal));
  1740. pContext->PntSprite.bEnabled = dwRSVal;
  1741. break;
  1742. case D3DRS_POINTSIZE_MIN:
  1743. DISPDBG((DBGLVL, "SET D3DRS_POINTSIZE_MIN = 0x%x",dwRSVal));
  1744. *(DWORD*)(&pContext->PntSprite.fSizeMin) = dwRSVal;
  1745. break;
  1746. case D3DRS_POINTSIZE_MAX:
  1747. DISPDBG((DBGLVL, "SET D3DRS_POINTSIZE_MAX = 0x%x",dwRSVal));
  1748. *(DWORD*)(&pContext->PntSprite.fSizeMax) = dwRSVal;
  1749. break;
  1750. // All of the following point sprite related render states are
  1751. // ignored by this driver since we are a Non-TnLHal driver.
  1752. case D3DRS_POINTSCALEENABLE:
  1753. DISPDBG((DBGLVL, "SET D3DRS_POINTSCALEENABLE = 0x%x",dwRSVal));
  1754. pContext->PntSprite.bScaleEnabled = dwRSVal;
  1755. break;
  1756. case D3DRS_POINTSCALE_A:
  1757. DISPDBG((DBGLVL, "SET D3DRS_POINTSCALE_A = 0x%x",dwRSVal));
  1758. *(DWORD*)(&pContext->PntSprite.fScale_A) = dwRSVal;
  1759. break;
  1760. case D3DRS_POINTSCALE_B:
  1761. DISPDBG((DBGLVL, "SET D3DRS_POINTSCALE_B = 0x%x",dwRSVal));
  1762. *(DWORD*)(&pContext->PntSprite.fScale_B) = dwRSVal;
  1763. break;
  1764. case D3DRS_POINTSCALE_C:
  1765. DISPDBG((DBGLVL, "SET D3DRS_POINTSCALE_C = 0x%x",dwRSVal));
  1766. *(DWORD*)(&pContext->PntSprite.fScale_C) = dwRSVal;
  1767. break;
  1768. #endif // DX8_POINTSPRITES
  1769. #if DX8_VERTEXSHADERS
  1770. case D3DRS_SOFTWAREVERTEXPROCESSING:
  1771. DISPDBG((DBGLVL, "SET D3DRS_SOFTWAREVERTEXPROCESSING = 0x%x",dwRSVal));
  1772. NOT_HANDLED;
  1773. break;
  1774. #endif // DX8_VERTEXSHADERS
  1775. #if DX8_DDI
  1776. case D3DRS_COLORWRITEENABLE:
  1777. {
  1778. DWORD dwColMask = 0x0;
  1779. DISPDBG((DBGLVL, "SET D3DRS_COLORWRITEENABLE = 0x%x",dwRSVal));
  1780. if (dwRSVal & D3DCOLORWRITEENABLE_RED)
  1781. {
  1782. dwColMask |= pContext->pSurfRenderInt->pixFmt.dwRBitMask;
  1783. }
  1784. if (dwRSVal & D3DCOLORWRITEENABLE_GREEN)
  1785. {
  1786. dwColMask |= pContext->pSurfRenderInt->pixFmt.dwGBitMask;
  1787. }
  1788. if (dwRSVal & D3DCOLORWRITEENABLE_BLUE)
  1789. {
  1790. dwColMask |= pContext->pSurfRenderInt->pixFmt.dwBBitMask;
  1791. }
  1792. if (dwRSVal & D3DCOLORWRITEENABLE_ALPHA)
  1793. {
  1794. dwColMask |= pContext->pSurfRenderInt->pixFmt.dwRGBAlphaBitMask;
  1795. }
  1796. // Replicate mask into higher word for P3 in 16 bpp mode
  1797. if (pContext->pSurfRenderInt->dwPixelSize == __GLINT_16BITPIXEL)
  1798. {
  1799. dwColMask |= (dwColMask << 16);
  1800. pContext->dwColorWriteSWMask = dwColMask;
  1801. }
  1802. else
  1803. {
  1804. pContext->dwColorWriteSWMask = 0xFFFFFFFF;
  1805. }
  1806. pContext->dwColorWriteHWMask = dwColMask;
  1807. SEND_P3_DATA(FBHardwareWriteMask, pContext->dwColorWriteHWMask);
  1808. DISPDBG((DBGLVL,"dwColMask = 0x%08x",dwColMask));
  1809. SEND_P3_DATA(FBSoftwareWriteMask, pContext->dwColorWriteSWMask);
  1810. }
  1811. break;
  1812. #endif // DX8_DDI
  1813. //----------------------------------------------------------------------
  1814. //----------------------------------------------------------------------
  1815. // The following are retired renderstates from DX8 but which we need to
  1816. // process correctly in order to run apps which use legacy interfaces
  1817. // These apps might send down the pipeline these renderstates and expect
  1818. // correct driver behavior !
  1819. //----------------------------------------------------------------------
  1820. //----------------------------------------------------------------------
  1821. case D3DRENDERSTATE_TEXTUREHANDLE:
  1822. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREHANDLE = 0x%x",dwRSVal));
  1823. if (dwRSVal != pdwTextureStageState_0[D3DTSS_TEXTUREMAP])
  1824. {
  1825. pdwTextureStageState_0[D3DTSS_TEXTUREMAP] = dwRSVal;
  1826. DIRTY_TEXTURE(pContext);
  1827. }
  1828. break;
  1829. #if DX7_ANTIALIAS
  1830. // DX7 uses D3DRENDERSTATE_ANTIALIAS.
  1831. case D3DRENDERSTATE_ANTIALIAS:
  1832. bDX7_Antialiasing = TRUE;
  1833. if (dwRSVal && pContext->pSurfRenderInt)
  1834. {
  1835. // Always reallocate alias buffer for DX7
  1836. // P3 driver supports only 2x2 (4) multi sample antialiasing
  1837. #if DX8_MULTISAMPLING
  1838. pContext->pSurfRenderInt->dwSampling = 4;
  1839. #endif // DX8_MULTISAMPLING
  1840. if (! _D3D_ST_CanRenderAntialiased(pContext, TRUE))
  1841. {
  1842. #if DX8_MULTISAMPLING
  1843. // Reset dwSampling in case of failure
  1844. pContext->pSurfRenderInt->dwSampling = 0;
  1845. #endif // DX8_MULTISAMPLING
  1846. P3_DMA_COMMIT_BUFFER();
  1847. return DDERR_OUTOFMEMORY;
  1848. }
  1849. }
  1850. // then fall through...
  1851. #endif // DX7_ANTIALIAS
  1852. #if DX8_MULTISAMPLING
  1853. // DX8 uses D3DRS_MULTISAMPLEANTIALIAS
  1854. case D3DRS_MULTISAMPLEANTIALIAS:
  1855. #endif // DX8_MULTISAMPLING
  1856. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  1857. DISPDBG((DBGLVL, "ChangeState: AntiAlias 0x%x",dwRSVal));
  1858. P3_DMA_COMMIT_BUFFER();
  1859. if (dwRSVal
  1860. #if DX8_MULTISAMPLING
  1861. && pContext->pSurfRenderInt->dwSampling
  1862. #endif // DX8_MULTISAMPLING
  1863. )
  1864. {
  1865. pSoftP3RX->P3RX_P3DeltaControl.FullScreenAA = __PERMEDIA_ENABLE;
  1866. *pFlags |= SURFACE_ANTIALIAS;
  1867. }
  1868. else
  1869. {
  1870. pSoftP3RX->P3RX_P3DeltaControl.FullScreenAA = __PERMEDIA_DISABLE;
  1871. *pFlags &= ~SURFACE_ANTIALIAS;
  1872. }
  1873. P3_DMA_GET_BUFFER_ENTRIES( 4 );
  1874. DIRTY_RENDER_OFFSETS(pContext);
  1875. break;
  1876. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  1877. case D3DRENDERSTATE_TEXTUREPERSPECTIVE:
  1878. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREPERSPECTIVE = 0x%x",dwRSVal));
  1879. if (dwRSVal != 0)
  1880. {
  1881. *pFlags |= SURFACE_PERSPCORRECT;
  1882. pSoftP3RX->P3RX_P3DeltaControl.ForceQ = 0;
  1883. }
  1884. else
  1885. {
  1886. *pFlags &= ~SURFACE_PERSPCORRECT;
  1887. pSoftP3RX->P3RX_P3DeltaControl.ForceQ = 1;
  1888. }
  1889. COPY_P3_DATA(DeltaControl, pSoftP3RX->P3RX_P3DeltaControl);
  1890. break;
  1891. case D3DRENDERSTATE_TEXTUREMAPBLEND:
  1892. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREMAPBLEND = 0x%x", dwRSVal));
  1893. *pFlags &= ~SURFACE_MODULATE;
  1894. switch(dwRSVal)
  1895. {
  1896. case D3DTBLEND_DECALMASK: // unsupported - do decal as fallback.
  1897. SET_BLEND_ERROR ( pContext, BSF_UNSUPPORTED_COLOR_OP );
  1898. // fall through
  1899. case D3DTBLEND_DECAL:
  1900. case D3DTBLEND_COPY:
  1901. pdwTextureStageState_0[D3DTSS_COLOROP] = D3DTOP_SELECTARG1;
  1902. pdwTextureStageState_0[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  1903. pdwTextureStageState_0[D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1;
  1904. pdwTextureStageState_0[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  1905. pdwTextureStageState_1[D3DTSS_COLOROP] = D3DTOP_DISABLE;
  1906. break;
  1907. case D3DTBLEND_MODULATEMASK: // unsupported - do modulate as fallback.
  1908. SET_BLEND_ERROR ( pContext, BSF_UNSUPPORTED_COLOR_OP );
  1909. // fall through
  1910. case D3DTBLEND_MODULATE:
  1911. pdwTextureStageState_0[D3DTSS_COLOROP] = D3DTOP_MODULATE;
  1912. pdwTextureStageState_0[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  1913. pdwTextureStageState_0[D3DTSS_COLORARG2] = D3DTA_DIFFUSE;
  1914. // In the changetexture* code we modify the below value,
  1915. // dependent on the SURFACE_MODULATE flag...
  1916. pdwTextureStageState_0[D3DTSS_ALPHAOP] = D3DTOP_SELECTARG1;
  1917. pdwTextureStageState_0[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  1918. pdwTextureStageState_0[D3DTSS_ALPHAARG2] = D3DTA_DIFFUSE;
  1919. pdwTextureStageState_1[D3DTSS_COLOROP] = D3DTOP_DISABLE;
  1920. *pFlags |= SURFACE_MODULATE;
  1921. break;
  1922. case D3DTBLEND_MODULATEALPHA:
  1923. pdwTextureStageState_0[D3DTSS_COLOROP] = D3DTOP_MODULATE;
  1924. pdwTextureStageState_0[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  1925. pdwTextureStageState_0[D3DTSS_COLORARG2] = D3DTA_DIFFUSE;
  1926. pdwTextureStageState_0[D3DTSS_ALPHAOP] = D3DTOP_MODULATE;
  1927. pdwTextureStageState_0[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  1928. pdwTextureStageState_0[D3DTSS_ALPHAARG2] = D3DTA_DIFFUSE;
  1929. pdwTextureStageState_1[D3DTSS_COLOROP] = D3DTOP_DISABLE;
  1930. break;
  1931. case D3DTBLEND_DECALALPHA:
  1932. pdwTextureStageState_0[D3DTSS_COLOROP] = D3DTOP_BLENDTEXTUREALPHA;
  1933. pdwTextureStageState_0[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  1934. pdwTextureStageState_0[D3DTSS_COLORARG2] = D3DTA_DIFFUSE;
  1935. pdwTextureStageState_0[D3DTSS_ALPHAOP] = D3DTOP_SELECTARG2;
  1936. pdwTextureStageState_0[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  1937. pdwTextureStageState_0[D3DTSS_ALPHAARG2] = D3DTA_DIFFUSE;
  1938. pdwTextureStageState_1[D3DTSS_COLOROP] = D3DTOP_DISABLE;
  1939. break;
  1940. case D3DTBLEND_ADD:
  1941. pdwTextureStageState_0[D3DTSS_COLOROP] = D3DTOP_ADD;
  1942. pdwTextureStageState_0[D3DTSS_COLORARG1] = D3DTA_TEXTURE;
  1943. pdwTextureStageState_0[D3DTSS_COLORARG2] = D3DTA_DIFFUSE;
  1944. pdwTextureStageState_0[D3DTSS_ALPHAOP] = D3DTOP_SELECTARG2;
  1945. pdwTextureStageState_0[D3DTSS_ALPHAARG1] = D3DTA_TEXTURE;
  1946. pdwTextureStageState_0[D3DTSS_ALPHAARG2] = D3DTA_DIFFUSE;
  1947. pdwTextureStageState_1[D3DTSS_COLOROP] = D3DTOP_DISABLE;
  1948. break;
  1949. default:
  1950. DISPDBG((ERRLVL,"ERROR: Unknown texture blend!"));
  1951. // This needs to be flagged here, because we don't know
  1952. // what effect it is meant to have on the TSS stuff.
  1953. SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  1954. break;
  1955. }
  1956. DIRTY_TEXTURE(pContext);
  1957. break;
  1958. case D3DRENDERSTATE_TEXTUREMAG:
  1959. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREMAG = 0x%x",dwRSVal));
  1960. switch(dwRSVal)
  1961. {
  1962. case D3DFILTER_NEAREST:
  1963. case D3DFILTER_MIPNEAREST:
  1964. pdwTextureStageState_0[D3DTSS_MAGFILTER] = D3DTFG_POINT;
  1965. break;
  1966. case D3DFILTER_LINEAR:
  1967. case D3DFILTER_LINEARMIPLINEAR:
  1968. case D3DFILTER_MIPLINEAR:
  1969. pdwTextureStageState_0[D3DTSS_MAGFILTER] = D3DTFG_LINEAR;
  1970. break;
  1971. default:
  1972. DISPDBG((ERRLVL,"ERROR: Unknown MAG filter!"));
  1973. break;
  1974. }
  1975. DIRTY_TEXTURE(pContext);
  1976. break;
  1977. case D3DRENDERSTATE_TEXTUREMIN:
  1978. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREMIN = 0x%x",dwRSVal));
  1979. switch(dwRSVal)
  1980. {
  1981. case D3DFILTER_NEAREST:
  1982. pdwTextureStageState_0[D3DTSS_MINFILTER] = D3DTFN_POINT;
  1983. pdwTextureStageState_0[D3DTSS_MIPFILTER] = D3DTFP_NONE;
  1984. break;
  1985. case D3DFILTER_MIPNEAREST:
  1986. pdwTextureStageState_0[D3DTSS_MINFILTER] = D3DTFN_POINT;
  1987. pdwTextureStageState_0[D3DTSS_MIPFILTER] = D3DTFP_POINT;
  1988. break;
  1989. case D3DFILTER_LINEARMIPNEAREST:
  1990. pdwTextureStageState_0[D3DTSS_MINFILTER] = D3DTFN_POINT;
  1991. pdwTextureStageState_0[D3DTSS_MIPFILTER] = D3DTFP_LINEAR;
  1992. break;
  1993. case D3DFILTER_LINEAR:
  1994. pdwTextureStageState_0[D3DTSS_MINFILTER] = D3DTFN_LINEAR;
  1995. pdwTextureStageState_0[D3DTSS_MIPFILTER] = D3DTFP_NONE;
  1996. break;
  1997. case D3DFILTER_MIPLINEAR:
  1998. pdwTextureStageState_0[D3DTSS_MINFILTER] = D3DTFN_LINEAR;
  1999. pdwTextureStageState_0[D3DTSS_MIPFILTER] = D3DTFP_POINT;
  2000. break;
  2001. case D3DFILTER_LINEARMIPLINEAR:
  2002. pdwTextureStageState_0[D3DTSS_MINFILTER] = D3DTFN_LINEAR;
  2003. pdwTextureStageState_0[D3DTSS_MIPFILTER] = D3DTFP_LINEAR;
  2004. break;
  2005. default:
  2006. DISPDBG((ERRLVL,"ERROR: Unknown MIN filter!"));
  2007. break;
  2008. }
  2009. DIRTY_TEXTURE(pContext);
  2010. break;
  2011. case D3DRENDERSTATE_WRAPU:
  2012. // map legacy WRAPU state through to controls for tex coord 0
  2013. DISPDBG((DBGLVL, "SET D3DRS_WRAPU = 0x%x",dwRSVal));
  2014. pContext->RenderStates[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_U;
  2015. pContext->RenderStates[D3DRENDERSTATE_WRAP0] |= ((dwRSVal) ? D3DWRAP_U : 0);
  2016. DIRTY_TEXTURE(pContext);
  2017. break;
  2018. case D3DRENDERSTATE_WRAPV:
  2019. // map legacy WRAPV state through to controls for tex coord 0
  2020. DISPDBG((DBGLVL, "SET D3DRS_WRAPV = 0x%x",dwRSVal));
  2021. pContext->RenderStates[D3DRENDERSTATE_WRAP0] &= ~D3DWRAP_V;
  2022. pContext->RenderStates[D3DRENDERSTATE_WRAP0] |= ((dwRSVal) ? D3DWRAP_V : 0);
  2023. DIRTY_TEXTURE(pContext);
  2024. break;
  2025. case D3DRENDERSTATE_TEXTUREADDRESS:
  2026. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREADDRESS = 0x%x",dwRSVal));
  2027. pdwTextureStageState_0[D3DTSS_ADDRESS] =
  2028. pdwTextureStageState_0[D3DTSS_ADDRESSU] =
  2029. pdwTextureStageState_0[D3DTSS_ADDRESSV] = dwRSVal;
  2030. DIRTY_TEXTURE(pContext);
  2031. break;
  2032. case D3DRENDERSTATE_TEXTUREADDRESSU:
  2033. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREADDRESSU = 0x%x",dwRSVal));
  2034. pdwTextureStageState_0[D3DTSS_ADDRESSU] = dwRSVal;
  2035. DIRTY_TEXTURE(pContext);
  2036. break;
  2037. case D3DRENDERSTATE_TEXTUREADDRESSV:
  2038. DISPDBG((DBGLVL, "SET D3DRS_TEXTUREADDRESSV = 0x%x",dwRSVal));
  2039. pdwTextureStageState_0[D3DTSS_ADDRESSV] = dwRSVal;
  2040. DIRTY_TEXTURE(pContext);
  2041. break;
  2042. case D3DRENDERSTATE_MIPMAPLODBIAS:
  2043. DISPDBG((DBGLVL, "SET D3DRS_MIPMAPLODBIAS = 0x%x",dwRSVal));
  2044. pdwTextureStageState_0[D3DTSS_MIPMAPLODBIAS] = dwRSVal;
  2045. DIRTY_TEXTURE(pContext);
  2046. break;
  2047. case D3DRENDERSTATE_BORDERCOLOR:
  2048. DISPDBG((DBGLVL, "SET D3DRS_BORDERCOLOR = 0x%x",dwRSVal));
  2049. pdwTextureStageState_0[D3DTSS_BORDERCOLOR] = dwRSVal;
  2050. DIRTY_TEXTURE(pContext);
  2051. break;
  2052. case D3DRENDERSTATE_STIPPLEPATTERN00:
  2053. case D3DRENDERSTATE_STIPPLEPATTERN01:
  2054. case D3DRENDERSTATE_STIPPLEPATTERN02:
  2055. case D3DRENDERSTATE_STIPPLEPATTERN03:
  2056. case D3DRENDERSTATE_STIPPLEPATTERN04:
  2057. case D3DRENDERSTATE_STIPPLEPATTERN05:
  2058. case D3DRENDERSTATE_STIPPLEPATTERN06:
  2059. case D3DRENDERSTATE_STIPPLEPATTERN07:
  2060. case D3DRENDERSTATE_STIPPLEPATTERN08:
  2061. case D3DRENDERSTATE_STIPPLEPATTERN09:
  2062. case D3DRENDERSTATE_STIPPLEPATTERN10:
  2063. case D3DRENDERSTATE_STIPPLEPATTERN11:
  2064. case D3DRENDERSTATE_STIPPLEPATTERN12:
  2065. case D3DRENDERSTATE_STIPPLEPATTERN13:
  2066. case D3DRENDERSTATE_STIPPLEPATTERN14:
  2067. case D3DRENDERSTATE_STIPPLEPATTERN15:
  2068. case D3DRENDERSTATE_STIPPLEPATTERN16:
  2069. case D3DRENDERSTATE_STIPPLEPATTERN17:
  2070. case D3DRENDERSTATE_STIPPLEPATTERN18:
  2071. case D3DRENDERSTATE_STIPPLEPATTERN19:
  2072. case D3DRENDERSTATE_STIPPLEPATTERN20:
  2073. case D3DRENDERSTATE_STIPPLEPATTERN21:
  2074. case D3DRENDERSTATE_STIPPLEPATTERN22:
  2075. case D3DRENDERSTATE_STIPPLEPATTERN23:
  2076. case D3DRENDERSTATE_STIPPLEPATTERN24:
  2077. case D3DRENDERSTATE_STIPPLEPATTERN25:
  2078. case D3DRENDERSTATE_STIPPLEPATTERN26:
  2079. case D3DRENDERSTATE_STIPPLEPATTERN27:
  2080. case D3DRENDERSTATE_STIPPLEPATTERN28:
  2081. case D3DRENDERSTATE_STIPPLEPATTERN29:
  2082. case D3DRENDERSTATE_STIPPLEPATTERN30:
  2083. case D3DRENDERSTATE_STIPPLEPATTERN31:
  2084. DISPDBG((DBGLVL, "SET D3DRS_STIPPLEPATTERN 2%d = 0x%x",
  2085. dwRSType - D3DRENDERSTATE_STIPPLEPATTERN00,
  2086. dwRSVal));
  2087. pContext->CurrentStipple
  2088. [(dwRSType - D3DRENDERSTATE_STIPPLEPATTERN00)] = dwRSVal;
  2089. if (!(*pFlags & SURFACE_ALPHASTIPPLE))
  2090. {
  2091. // Flat-Stippled Alpha is not on, so use the current stipple pattern
  2092. SEND_P3_DATA_OFFSET(AreaStipplePattern0,
  2093. (DWORD)dwRSVal, dwRSType - D3DRENDERSTATE_STIPPLEPATTERN00);
  2094. }
  2095. break;
  2096. case D3DRENDERSTATE_ROP2:
  2097. DISPDBG((DBGLVL, "SET D3DRS_ROP2 = 0x%x",dwRSVal));
  2098. NOT_HANDLED;
  2099. break;
  2100. case D3DRENDERSTATE_PLANEMASK:
  2101. DISPDBG((DBGLVL, "SET D3DRS_PLANEMASK = 0x%x",dwRSVal));
  2102. SEND_P3_DATA(FBHardwareWriteMask, (DWORD)dwRSVal);
  2103. break;
  2104. case D3DRENDERSTATE_MONOENABLE:
  2105. DISPDBG((DBGLVL, "SET D3DRS_MONOENABLE = 0x%x", dwRSVal));
  2106. if (dwRSVal)
  2107. {
  2108. *pFlags |= SURFACE_MONO;
  2109. }
  2110. else
  2111. {
  2112. *pFlags &= ~SURFACE_MONO;
  2113. }
  2114. break;
  2115. case D3DRENDERSTATE_SUBPIXEL:
  2116. DISPDBG((DBGLVL, "SET D3DRS_SUBPIXEL = 0x%x", dwRSVal));
  2117. NOT_HANDLED;
  2118. break;
  2119. case D3DRENDERSTATE_SUBPIXELX:
  2120. DISPDBG((DBGLVL, "SET D3DRS_SUBPIXELX = 0x%x", dwRSVal));
  2121. NOT_HANDLED;
  2122. break;
  2123. case D3DRENDERSTATE_STIPPLEENABLE:
  2124. DISPDBG((DBGLVL, "SET D3DRS_STIPPLEENABLE = 0x%x", dwRSVal));
  2125. if (dwRSVal)
  2126. {
  2127. if (!(*pFlags & SURFACE_ALPHASTIPPLE))
  2128. {
  2129. RENDER_AREA_STIPPLE_ENABLE(pContext->RenderCommand);
  2130. }
  2131. pContext->bKeptStipple = TRUE;
  2132. }
  2133. else
  2134. {
  2135. RENDER_AREA_STIPPLE_DISABLE(pContext->RenderCommand);
  2136. pContext->bKeptStipple = FALSE;
  2137. }
  2138. break;
  2139. case D3DRENDERSTATE_COLORKEYENABLE:
  2140. DISPDBG((DBGLVL, "SET D3DRS_COLORKEYENABLE = 0x%x",dwRSVal));
  2141. DIRTY_TEXTURE(pContext);
  2142. DIRTY_ALPHATEST(pContext);
  2143. DIRTY_PIPELINEORDER(pContext);
  2144. DIRTY_OPTIMIZE_ALPHA(pContext);
  2145. break;
  2146. //----------------------------------------------------------------------
  2147. //----------------------------------------------------------------------
  2148. // The default case handles any other unknown renderstate
  2149. //----------------------------------------------------------------------
  2150. //----------------------------------------------------------------------
  2151. default:
  2152. // There are a few states that we just don't understand.
  2153. DISPDBG((WRNLVL, "_D3D_ST_ProcessOneRenderState"
  2154. " Unhandled opcode = %d", dwRSType));
  2155. //SET_BLEND_ERROR ( pContext, BSF_UNDEFINED_STATE );
  2156. break;
  2157. }
  2158. // Commit DMA Buffer
  2159. P3_DMA_COMMIT_BUFFER();
  2160. DBG_EXIT(_D3D_ST_ProcessOneRenderState,0);
  2161. return DD_OK;
  2162. } // _D3D_ST_ProcessOneRenderState
  2163. //-----------------------------------------------------------------------------
  2164. //
  2165. // _D3D_ST_ProcessRenderStates
  2166. //
  2167. // Updates the context's renderstates processing an array of D3DSTATE
  2168. // structures with dwStateCount elements in it. bDoOverride indicates
  2169. // if legacy state overrides are to be taken into account.
  2170. //-----------------------------------------------------------------------------
  2171. DWORD
  2172. _D3D_ST_ProcessRenderStates(
  2173. P3_D3DCONTEXT* pContext,
  2174. DWORD dwStateCount,
  2175. D3DSTATE *pState,
  2176. BOOL bDoOverride)
  2177. {
  2178. DWORD dwCurrState;
  2179. DBG_ENTRY(_D3D_ST_ProcessRenderStates);
  2180. DISPDBG((DBGLVL, "_D3D_ST_ProcessRenderStates: "
  2181. "Valid Context =%08lx, dwStateCount=%d",
  2182. pContext, dwStateCount));
  2183. for (dwCurrState = 0; dwCurrState < dwStateCount; dwCurrState++, pState++)
  2184. {
  2185. DWORD dwRSType = (DWORD) pState->drstRenderStateType;
  2186. DWORD dwRSVal = pState->dwArg[0];
  2187. // Override states for legacy API apps
  2188. if (bDoOverride)
  2189. {
  2190. // Make sure the override is within the valid range
  2191. if ((dwRSType >= (D3DSTATE_OVERRIDE_BIAS + MAX_STATE)) ||
  2192. (dwRSType < 1))
  2193. {
  2194. DISPDBG((ERRLVL, "_D3D_ST_ProcessRenderStates: "
  2195. "Invalid render state %d",
  2196. dwRSType));
  2197. continue;
  2198. }
  2199. if (IS_OVERRIDE(dwRSType))
  2200. {
  2201. DWORD override = GET_OVERRIDE(dwRSType);
  2202. if (dwRSVal)
  2203. {
  2204. DISPDBG((DBGLVL, "_D3D_ST_ProcessRenderStates: "
  2205. "setting override for state %d",
  2206. override));
  2207. STATESET_SET(pContext->overrides, override);
  2208. }
  2209. else
  2210. {
  2211. DISPDBG((DBGLVL, "_D3D_ST_ProcessRenderStates: "
  2212. "clearing override for state %d",
  2213. override));
  2214. STATESET_CLEAR(pContext->overrides, override);
  2215. }
  2216. continue;
  2217. }
  2218. if (STATESET_ISSET(pContext->overrides, dwRSType))
  2219. {
  2220. DISPDBG((DBGLVL, "_D3D_ST_ProcessRenderStates: "
  2221. "state %d is overridden, ignoring",
  2222. dwRSType));
  2223. continue;
  2224. }
  2225. }
  2226. // Make sure the render state is within the valid range
  2227. if ((dwRSType >= MAX_STATE) || (dwRSType < 1))
  2228. {
  2229. continue;
  2230. }
  2231. #if DX7_D3DSTATEBLOCKS
  2232. if (pContext->bStateRecMode)
  2233. {
  2234. // Record this render state into the
  2235. // current state set being recorded
  2236. _D3D_SB_RecordStateSetRS(pContext, dwRSType, dwRSVal);
  2237. }
  2238. else
  2239. #endif //DX7_D3DSTATEBLOCKS
  2240. {
  2241. // Process the next render state
  2242. _D3D_ST_ProcessOneRenderState(pContext, dwRSType, dwRSVal);
  2243. }
  2244. }
  2245. DBG_EXIT(_D3D_ST_ProcessRenderStates,0);
  2246. return DD_OK;
  2247. } // _D3D_ST_ProcessRenderStates
  2248. //-----------------------------------------------------------------------------
  2249. //
  2250. // _D3D_ST_RealizeHWStateChanges
  2251. //
  2252. // Verifies if there are pending hardware render state changes to set up,
  2253. // before proceeding to rasterize/render primitives. This might be convenient
  2254. // if the combined setting of some renderstates allows us to optimize the
  2255. // hardware setup in some way.
  2256. //
  2257. //-----------------------------------------------------------------------------
  2258. BOOL
  2259. _D3D_ST_RealizeHWStateChanges(
  2260. P3_D3DCONTEXT* pContext)
  2261. {
  2262. P3_THUNKEDDATA *pThisDisplay;
  2263. DBG_ENTRY(_D3D_ST_RealizeHWStateChanges);
  2264. pThisDisplay = pContext->pThisDisplay;
  2265. // Check if a flip or a mode change have happened. If so, we will
  2266. // need to setup the render target registers before doing any
  2267. // new rendering
  2268. if (pContext->ModeChangeCount != pThisDisplay->ModeChangeCount)
  2269. {
  2270. pContext->ModeChangeCount = pThisDisplay->ModeChangeCount;
  2271. pThisDisplay->bFlippedSurface = TRUE;
  2272. }
  2273. if (pThisDisplay->bFlippedSurface)
  2274. {
  2275. DIRTY_RENDER_OFFSETS(pContext);
  2276. }
  2277. // If there are any pending renderstates to process, do so
  2278. if ( pContext->dwDirtyFlags )
  2279. {
  2280. // Now setup any pending hardware state necessary to correctly
  2281. // render our primitives
  2282. __ST_HandleDirtyP3State( pThisDisplay, pContext);
  2283. // Mark the context as up to date
  2284. pContext->dwDirtyFlags = 0;
  2285. // Verify that the working set textures are valid so we may proceed
  2286. // with rendering. Otherwise we will abort the attempt to render
  2287. // anything
  2288. if (!pContext->bTextureValid)
  2289. {
  2290. DISPDBG((ERRLVL,"ERROR: _D3D_ST_RealizeHWStateChanges:"
  2291. "Invalid Texture Handle, not rendering"));
  2292. // re-dirty the texture setup so that we may try again later
  2293. pContext->dwDirtyFlags |= CONTEXT_DIRTY_TEXTURE;
  2294. DBG_EXIT(_D3D_ST_RealizeHWStateChanges,1);
  2295. return FALSE;
  2296. }
  2297. }
  2298. DBG_EXIT(_D3D_ST_RealizeHWStateChanges,0);
  2299. return TRUE;
  2300. } // _D3D_ST_RealizeHWStateChanges