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.

1439 lines
58 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3dcntxt.c
  8. *
  9. * Content: Main context callbacks for D3D
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "glint.h"
  15. #if W95_DDRAW
  16. #include <dmemmgr.h>
  17. #endif
  18. #include "dma.h"
  19. #include "tag.h"
  20. //-----------------------------------------------------------------------------
  21. // ****************************************************************************
  22. // *********************** D3D Context handle management **********************
  23. // ****************************************************************************
  24. //-----------------------------------------------------------------------------
  25. // Here we abstract the managment of context structures. If you wish to modify
  26. // the way these are managed, this is the place to perform the modification
  27. //-----------------------------------------------------------------------------
  28. // Maximum simultaneous number of contexts we can keep track of
  29. #define MAX_CONTEXT_NUM 200
  30. // Since these variables are global they are forced
  31. // into shared data segment by the build.
  32. P3_D3DCONTEXT* g_D3DContextSlots[MAX_CONTEXT_NUM] = {NULL};
  33. BOOL g_D3DInitialised = FALSE;
  34. //-----------------------------------------------------------------------------
  35. //
  36. // _D3D_CTX_HandleInitialization
  37. //
  38. // Initialize the handle data structures (array) . Be careful not to initialize
  39. // it twice (between mode changes for example) as this info has to be persistent
  40. //-----------------------------------------------------------------------------
  41. VOID _D3D_CTX_HandleInitialization(VOID)
  42. {
  43. DWORD i;
  44. // Do only the first time the driver is loaded.
  45. if (g_D3DInitialised == FALSE)
  46. {
  47. // Clear the contexts. Since this is done only once, lets do it right,
  48. // rather than just clearing with a memset(g_D3DContextSlots,0,size);
  49. for (i = 0; i < MAX_CONTEXT_NUM; i++)
  50. {
  51. g_D3DContextSlots[i] = NULL;
  52. }
  53. // This will assure we only initialize the data once
  54. g_D3DInitialised = TRUE;
  55. }
  56. } // _D3D_CTX_HandleInitialization
  57. //-----------------------------------------------------------------------------
  58. // __CTX_NewHandle
  59. //
  60. // Returns a valid context handle number to use in all D3D callbacks and ready
  61. // to be associated with a P3_D3DCONTEXT structure
  62. //-----------------------------------------------------------------------------
  63. DWORD __CTX_NewHandle(VOID)
  64. {
  65. DWORD dwSlotNum;
  66. // Find an empty slot.
  67. for (dwSlotNum = 1; dwSlotNum < MAX_CONTEXT_NUM; dwSlotNum++)
  68. {
  69. if (g_D3DContextSlots[dwSlotNum] == NULL)
  70. {
  71. return dwSlotNum;
  72. }
  73. }
  74. DISPDBG((WRNLVL,"WARN:No empty context slots left"));
  75. return 0; // no empty slots left, check for this return value!
  76. } // __CTX_NewHandle
  77. //-----------------------------------------------------------------------------
  78. // __CTX_AssocPtrToHandle
  79. //
  80. // Associate a pointer (to a P3_D3DCONTEXT) with this context handle
  81. //-----------------------------------------------------------------------------
  82. VOID __CTX_AssocPtrToHandle(DWORD hHandle,P3_D3DCONTEXT* pContext)
  83. {
  84. ASSERTDD(hHandle < MAX_CONTEXT_NUM,
  85. "Accessing g_D3DContextSlots out of bounds");
  86. g_D3DContextSlots[hHandle] = pContext;
  87. } // __CTX_AssocPtrToHandle
  88. //-----------------------------------------------------------------------------
  89. // _D3D_CTX_HandleToPtr
  90. //
  91. // Returns the pointer associated to this context handle
  92. //-----------------------------------------------------------------------------
  93. P3_D3DCONTEXT*
  94. _D3D_CTX_HandleToPtr(ULONG_PTR hHandle)
  95. {
  96. return g_D3DContextSlots[(DWORD)(hHandle)];
  97. } // _D3D_CTX_HandleToPtr
  98. //-----------------------------------------------------------------------------
  99. // __CTX_HandleRelease
  100. //
  101. // This marks the handle number as "free" so it can be reused again when
  102. // a new D3D context is created
  103. //-----------------------------------------------------------------------------
  104. VOID __CTX_HandleRelease(DWORD hHandle)
  105. {
  106. ASSERTDD(hHandle < MAX_CONTEXT_NUM,
  107. "Accessing g_D3DContextSlots out of bounds");
  108. g_D3DContextSlots[hHandle] = NULL;
  109. } // __CTX_HandleRelease
  110. //-----------------------------------------------------------------------------
  111. // ****************************************************************************
  112. // ***********Hardware specific context and state initial setup ***************
  113. // ****************************************************************************
  114. //-----------------------------------------------------------------------------
  115. //-----------------------------------------------------------------------------
  116. //
  117. // __CTX_CleanDirect3DContext
  118. //
  119. // After it has been decided that a context is indeed still active
  120. // and is being freed, this function walks along cleaning everything
  121. // up. Note it can be called either as a result of a D3DContextDestroy,
  122. // or as a result of the app exiting without freeing the context, or
  123. // as the result of an error whilst creating the context.
  124. //
  125. //-----------------------------------------------------------------------------
  126. VOID
  127. __CTX_CleanDirect3DContext(
  128. P3_D3DCONTEXT* pContext)
  129. {
  130. P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
  131. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  132. // Free any antialiasing buffer we might have left around in vidmem
  133. if (pContext->dwAliasBackBuffer != 0)
  134. {
  135. _DX_LIN_FreeLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
  136. pContext->dwAliasBackBuffer);
  137. pContext->dwAliasBackBuffer = 0;
  138. pContext->dwAliasPixelOffset = 0;
  139. }
  140. if (pContext->dwAliasZBuffer != 0)
  141. {
  142. _DX_LIN_FreeLinearMemory(&pThisDisplay->LocalVideoHeap0Info,
  143. pContext->dwAliasZBuffer);
  144. pContext->dwAliasZBuffer = 0;
  145. pContext->dwAliasZPixelOffset = 0;
  146. }
  147. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  148. //@@BEGIN_DDKSPLIT
  149. #if DX7_VIDMEM_VB
  150. // Free up the useful DrawPrim buffers.
  151. // Yes, these are device-global rather than per-context, but that's fine
  152. // since whenever they are used, a macro checks to see if they are big
  153. // enough and if not re-allocates them. The data does not need to
  154. // survive across calls.
  155. // I'm doing the free here instead of end-of-driver-day because there
  156. // is no elegant place to do it then.
  157. if ( (void *)pThisDisplay->DrawPrimIndexBufferMem != NULL )
  158. {
  159. ASSERTDD ( pThisDisplay->DrawPrimIndexBufferMemSize > 0,
  160. "** D3DContextDestroy - DrawPrimIndexBufferMemSize "
  161. "negative or zero, but memory pointer not NULL" );
  162. HEAP_FREE ( (void *)pThisDisplay->DrawPrimIndexBufferMem );
  163. pThisDisplay->DrawPrimIndexBufferMem = (ULONG_PTR)NULL;
  164. pThisDisplay->DrawPrimIndexBufferMemSize = 0;
  165. }
  166. else
  167. {
  168. ASSERTDD ( pThisDisplay->DrawPrimIndexBufferMemSize == 0,
  169. "** D3DContextDestroy - DrawPrimIndexBufferMemSize "
  170. "not zero, but memory pointer is NULL" );
  171. pThisDisplay->DrawPrimIndexBufferMemSize = 0;
  172. }
  173. if ( (void *)pThisDisplay->DrawPrimVertexBufferMem != NULL )
  174. {
  175. ASSERTDD ( pThisDisplay->DrawPrimVertexBufferMemSize > 0,
  176. "** D3DContextDestroy - DrawPrimVertexBufferMemSize "
  177. "negative or zero, but memory pointer not NULL" );
  178. HEAP_FREE ( (void *)pThisDisplay->DrawPrimVertexBufferMem );
  179. pThisDisplay->DrawPrimVertexBufferMem = (ULONG_PTR)NULL;
  180. pThisDisplay->DrawPrimVertexBufferMemSize = 0;
  181. }
  182. else
  183. {
  184. ASSERTDD ( pThisDisplay->DrawPrimVertexBufferMemSize == 0,
  185. "** D3DContextDestroy - DrawPrimVertexBufferMemSize "
  186. "not zero, but memory pointer is NULL" );
  187. pThisDisplay->DrawPrimVertexBufferMemSize = 0;
  188. }
  189. #endif DX7_VIDMEM_VB
  190. //@@END_DDKSPLIT
  191. #if DX7_D3DSTATEBLOCKS
  192. // Free up any remaining state sets
  193. _D3D_SB_DeleteAllStateSets(pContext);
  194. #endif //DX7_D3DSTATEBLOCKS
  195. #if DX7_PALETTETEXTURE
  196. // Destroy the per context palette pointer array
  197. if (pContext->pPalettePointerArray)
  198. {
  199. PA_DestroyArray(pContext->pPalettePointerArray, NULL);
  200. }
  201. #endif
  202. } // __CTX_CleanDirect3DContext()
  203. //-----------------------------------------------------------------------------
  204. //
  205. // __CTX_Perm3_DisableUnits
  206. //
  207. // Disables all the mode registers to give us a clean start.
  208. //
  209. //-----------------------------------------------------------------------------
  210. static VOID
  211. __CTX_Perm3_DisableUnits(
  212. P3_D3DCONTEXT* pContext)
  213. {
  214. P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
  215. P3_DMA_DEFS();
  216. P3_DMA_GET_BUFFER();
  217. P3_ENSURE_DX_SPACE(128);
  218. WAIT_FIFO(32);
  219. SEND_P3_DATA(RasterizerMode, __PERMEDIA_DISABLE);
  220. SEND_P3_DATA(AreaStippleMode, __PERMEDIA_DISABLE);
  221. SEND_P3_DATA(LineStippleMode, __PERMEDIA_DISABLE);
  222. SEND_P3_DATA(ScissorMode, __PERMEDIA_DISABLE);
  223. SEND_P3_DATA(DepthMode, __PERMEDIA_DISABLE);
  224. SEND_P3_DATA(ColorDDAMode, __PERMEDIA_DISABLE);
  225. SEND_P3_DATA(FogMode, __PERMEDIA_DISABLE);
  226. SEND_P3_DATA(AntialiasMode, __PERMEDIA_DISABLE);
  227. SEND_P3_DATA(AlphaTestMode, __PERMEDIA_DISABLE);
  228. SEND_P3_DATA(LBReadMode, __PERMEDIA_DISABLE);
  229. SEND_P3_DATA(Window, __PERMEDIA_DISABLE);
  230. SEND_P3_DATA(StencilMode, __PERMEDIA_DISABLE);
  231. SEND_P3_DATA(LBWriteMode, __PERMEDIA_DISABLE);
  232. SEND_P3_DATA(FBReadMode, __PERMEDIA_DISABLE);
  233. SEND_P3_DATA(PatternRAMMode, __PERMEDIA_DISABLE);
  234. WAIT_FIFO(18);
  235. SEND_P3_DATA(DitherMode, __PERMEDIA_DISABLE);
  236. SEND_P3_DATA(AlphaBlendMode, __PERMEDIA_DISABLE);
  237. SEND_P3_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
  238. SEND_P3_DATA(FBWriteMode, __PERMEDIA_DISABLE);
  239. SEND_P3_DATA(StatisticMode, __PERMEDIA_DISABLE);
  240. SEND_P3_DATA(PixelSize, __PERMEDIA_DISABLE);
  241. SEND_P3_DATA(FBSourceData, __PERMEDIA_DISABLE);
  242. SEND_P3_DATA(LBWriteFormat, __PERMEDIA_DISABLE);
  243. WAIT_FIFO(32);
  244. SEND_P3_DATA(TextureReadMode, __PERMEDIA_DISABLE);
  245. SEND_P3_DATA(TextureCoordMode, __PERMEDIA_DISABLE);
  246. SEND_P3_DATA(ChromaTestMode, __PERMEDIA_DISABLE);
  247. SEND_P3_DATA(FilterMode, __PERMEDIA_DISABLE);
  248. SEND_P3_DATA(LUTTransfer, __PERMEDIA_DISABLE);
  249. SEND_P3_DATA(LUTIndex, __PERMEDIA_DISABLE);
  250. SEND_P3_DATA(LUTAddress, __PERMEDIA_DISABLE);
  251. SEND_P3_DATA(LUTMode, __PERMEDIA_DISABLE);
  252. if (TLCHIP_GAMMA)
  253. {
  254. WAIT_FIFO(32);
  255. SEND_P3_DATA(Light0Mode, 0);
  256. SEND_P3_DATA(Light1Mode, 0);
  257. SEND_P3_DATA(Light2Mode, 0);
  258. SEND_P3_DATA(Light3Mode, 0);
  259. SEND_P3_DATA(Light4Mode, 0);
  260. SEND_P3_DATA(Light5Mode, 0);
  261. SEND_P3_DATA(Light6Mode, 0);
  262. SEND_P3_DATA(Light7Mode, 0);
  263. SEND_P3_DATA(Light8Mode, 0);
  264. SEND_P3_DATA(Light9Mode, 0);
  265. SEND_P3_DATA(Light10Mode, 0);
  266. SEND_P3_DATA(Light11Mode, 0);
  267. SEND_P3_DATA(Light12Mode, 0);
  268. SEND_P3_DATA(Light13Mode, 0);
  269. SEND_P3_DATA(Light14Mode, 0);
  270. SEND_P3_DATA(Light15Mode, 0);
  271. WAIT_FIFO(32);
  272. SEND_P3_DATA(TransformMode, 0);
  273. SEND_P3_DATA(MaterialMode, 0);
  274. SEND_P3_DATA(GeometryMode, 0);
  275. SEND_P3_DATA(LightingMode, 0);
  276. SEND_P3_DATA(ColorMaterialMode, 0);
  277. SEND_P3_DATA(NormaliseMode, 0);
  278. SEND_P3_DATA(LineMode, 0);
  279. SEND_P3_DATA(TriangleMode, 0);
  280. }
  281. P3_DMA_COMMIT_BUFFER();
  282. } // __CTX_Perm3_DisableUnits
  283. //-----------------------------------------------------------------------------
  284. //
  285. // __CTX_Perm3_SetupD3D_HWDefaults
  286. //
  287. // Sets up the initial value of registers for this D3D context. This is done
  288. // within the current chip context (D3D_OPERATION) so that when we return to
  289. // it from DD or GDI we get the correct register values restored
  290. //
  291. //-----------------------------------------------------------------------------
  292. void
  293. __CTX_Perm3_SetupD3D_HWDefaults(
  294. P3_D3DCONTEXT* pContext)
  295. {
  296. P3_SOFTWARECOPY* pSoftP3RX = &pContext->SoftCopyGlint;
  297. P3_THUNKEDDATA *pThisDisplay = pContext->pThisDisplay;
  298. P3_DMA_DEFS();
  299. // Make sure we our working within the right chip-regs context
  300. D3D_OPERATION(pContext, pThisDisplay);
  301. // Initially turn off all hardware units.
  302. // We will turn on back whatever units are needed.
  303. __CTX_Perm3_DisableUnits(pContext);
  304. // Set up VertexControl register in HostIn unit.
  305. pSoftP3RX->P3RX_P3VertexControl.Size = 1;
  306. pSoftP3RX->P3RX_P3VertexControl.Flat = __PERMEDIA_DISABLE;
  307. pSoftP3RX->P3RX_P3VertexControl.ReadAll = __PERMEDIA_DISABLE;
  308. pSoftP3RX->P3RX_P3VertexControl.SkipFlags = __PERMEDIA_DISABLE;
  309. pSoftP3RX->P3RX_P3VertexControl.CacheEnable = __PERMEDIA_ENABLE;
  310. pSoftP3RX->P3RX_P3VertexControl.OGL = __PERMEDIA_DISABLE;
  311. pSoftP3RX->P3RX_P3VertexControl.Line2D = __PERMEDIA_DISABLE;
  312. // Constant LBReadMode setup
  313. pSoftP3RX->LBReadMode.WindowOrigin = __GLINT_TOP_LEFT_WINDOW_ORIGIN; // Top left
  314. pSoftP3RX->LBReadMode.DataType = __GLINT_LBDEFAULT; // default
  315. pSoftP3RX->LBReadMode.ReadSourceEnable = __PERMEDIA_DISABLE;
  316. pSoftP3RX->LBReadMode.ReadDestinationEnable = __PERMEDIA_DISABLE;
  317. // Constant DitherMode setup
  318. pSoftP3RX->DitherMode.ColorOrder = COLOR_MODE;
  319. pSoftP3RX->DitherMode.XOffset = DITHER_XOFFSET;
  320. pSoftP3RX->DitherMode.YOffset = DITHER_YOFFSET;
  321. pSoftP3RX->DitherMode.UnitEnable = __PERMEDIA_ENABLE;
  322. // Alpha Blend Mode Setup
  323. pSoftP3RX->P3RXAlphaBlendColorMode.Enable = __PERMEDIA_DISABLE;
  324. pSoftP3RX->P3RXAlphaBlendColorMode.SourceBlend = 0;
  325. pSoftP3RX->P3RXAlphaBlendColorMode.DestBlend = 0;
  326. pSoftP3RX->P3RXAlphaBlendColorMode.SourceTimesTwo = __PERMEDIA_DISABLE;
  327. pSoftP3RX->P3RXAlphaBlendColorMode.DestTimesTwo = __PERMEDIA_DISABLE;
  328. pSoftP3RX->P3RXAlphaBlendColorMode.InvertSource = __PERMEDIA_DISABLE;
  329. pSoftP3RX->P3RXAlphaBlendColorMode.InvertDest = __PERMEDIA_DISABLE;
  330. pSoftP3RX->P3RXAlphaBlendColorMode.ColorFormat = P3RX_ALPHABLENDMODE_COLORFORMAT_8888;
  331. pSoftP3RX->P3RXAlphaBlendColorMode.ColorOrder = COLOR_MODE;
  332. pSoftP3RX->P3RXAlphaBlendColorMode.ColorConversion = P3RX_ALPHABLENDMODE_CONVERT_SHIFT;
  333. pSoftP3RX->P3RXAlphaBlendColorMode.ConstantSource = __PERMEDIA_DISABLE;
  334. pSoftP3RX->P3RXAlphaBlendColorMode.ConstantDest = __PERMEDIA_DISABLE;
  335. pSoftP3RX->P3RXAlphaBlendColorMode.Operation = __PERMEDIA_DISABLE;
  336. pSoftP3RX->P3RXAlphaBlendColorMode.SwapSD = __PERMEDIA_DISABLE;
  337. pSoftP3RX->P3RXAlphaBlendAlphaMode.Enable = __PERMEDIA_DISABLE;
  338. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceBlend = 0;
  339. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestBlend = 0;
  340. pSoftP3RX->P3RXAlphaBlendAlphaMode.SourceTimesTwo = __PERMEDIA_DISABLE;
  341. pSoftP3RX->P3RXAlphaBlendAlphaMode.DestTimesTwo = __PERMEDIA_DISABLE;
  342. pSoftP3RX->P3RXAlphaBlendAlphaMode.InvertSource = __PERMEDIA_DISABLE;
  343. pSoftP3RX->P3RXAlphaBlendAlphaMode.InvertDest = __PERMEDIA_DISABLE;
  344. pSoftP3RX->P3RXAlphaBlendAlphaMode.NoAlphaBuffer = __PERMEDIA_DISABLE;
  345. pSoftP3RX->P3RXAlphaBlendAlphaMode.AlphaType = 0; // Use GL Blend modes
  346. pSoftP3RX->P3RXAlphaBlendAlphaMode.AlphaConversion = P3RX_ALPHABLENDMODE_CONVERT_SCALE;
  347. pSoftP3RX->P3RXAlphaBlendAlphaMode.ConstantSource = __PERMEDIA_DISABLE;
  348. pSoftP3RX->P3RXAlphaBlendAlphaMode.ConstantDest = __PERMEDIA_DISABLE;
  349. pSoftP3RX->P3RXAlphaBlendAlphaMode.Operation = __PERMEDIA_DISABLE;
  350. DIRTY_ALPHABLEND(pContext);
  351. // Local Buffer Read format bits that don't change
  352. pSoftP3RX->P3RXLBReadFormat.GIDPosition = 0;
  353. pSoftP3RX->P3RXLBReadFormat.GIDWidth = 0; // No GID
  354. pSoftP3RX->P3RXLBReadFormat.StencilPosition = 0;
  355. pSoftP3RX->P3RXLBReadFormat.StencilWidth = 0; // No Stencil
  356. pSoftP3RX->P3RXLBWriteFormat.GIDPosition = 0;
  357. pSoftP3RX->P3RXLBWriteFormat.GIDWidth = 0; // No GID
  358. pSoftP3RX->P3RXLBWriteFormat.StencilPosition = 0;
  359. pSoftP3RX->P3RXLBWriteFormat.StencilWidth = 0; // No Stencil
  360. // Never do a source read operation
  361. pSoftP3RX->P3RXLBSourceReadMode.Enable = 0;
  362. pSoftP3RX->P3RXLBSourceReadMode.Origin = 0;
  363. pSoftP3RX->P3RXLBSourceReadMode.StripeHeight = 0;
  364. pSoftP3RX->P3RXLBSourceReadMode.StripePitch = 0;
  365. pSoftP3RX->P3RXLBSourceReadMode.PrefetchEnable = 0;
  366. // Default is to read the Z Buffer
  367. pSoftP3RX->P3RXLBDestReadMode.Enable = 1;
  368. pSoftP3RX->P3RXLBDestReadMode.Origin = 0;
  369. pSoftP3RX->P3RXLBDestReadMode.StripeHeight = 0;
  370. pSoftP3RX->P3RXLBDestReadMode.StripePitch = 0;
  371. pSoftP3RX->P3RXLBDestReadMode.PrefetchEnable = 0;
  372. // Local Buffer Write mode
  373. pSoftP3RX->P3RXLBWriteMode.WriteEnable = __PERMEDIA_ENABLE; // Initially allow LB Writes
  374. pSoftP3RX->P3RXLBWriteMode.StripeHeight = 0;
  375. pSoftP3RX->P3RXLBWriteMode.StripePitch = 0;
  376. pSoftP3RX->P3RXLBWriteMode.Origin = __GLINT_TOP_LEFT_WINDOW_ORIGIN;
  377. pSoftP3RX->P3RXLBWriteMode.Operation = __PERMEDIA_DISABLE;
  378. // Frame Buffer WriteMode
  379. pSoftP3RX->P3RXFBWriteMode.WriteEnable = __PERMEDIA_ENABLE;
  380. pSoftP3RX->P3RXFBWriteMode.Replicate = __PERMEDIA_DISABLE;
  381. pSoftP3RX->P3RXFBWriteMode.OpaqueSpan = __PERMEDIA_DISABLE;
  382. pSoftP3RX->P3RXFBWriteMode.StripePitch = P3RX_STRIPE_1;
  383. pSoftP3RX->P3RXFBWriteMode.StripeHeight = P3RX_STRIPE_1;
  384. pSoftP3RX->P3RXFBWriteMode.Enable0 = __PERMEDIA_ENABLE;
  385. // FB Destination reads
  386. pSoftP3RX->P3RXFBDestReadMode.ReadEnable = __PERMEDIA_DISABLE;
  387. pSoftP3RX->P3RXFBDestReadMode.Enable0 = __PERMEDIA_ENABLE;
  388. // FB Source reads
  389. pSoftP3RX->P3RXFBSourceReadMode.ReadEnable = __PERMEDIA_DISABLE;
  390. // Depth comparisons
  391. pSoftP3RX->P3RXDepthMode.WriteMask = __PERMEDIA_ENABLE;
  392. pSoftP3RX->P3RXDepthMode.CompareMode = __GLINT_DEPTH_COMPARE_MODE_ALWAYS;
  393. pSoftP3RX->P3RXDepthMode.NewDepthSource = __GLINT_DEPTH_SOURCE_DDA;
  394. pSoftP3RX->P3RXDepthMode.Enable = __PERMEDIA_DISABLE;
  395. #define NLZ 0
  396. #if NLZ
  397. pSoftP3RX->P3RXDepthMode.Normalise = __PERMEDIA_DISABLE;
  398. pSoftP3RX->P3RXDepthMode.NonLinearZ = __PERMEDIA_ENABLE;
  399. #else
  400. pSoftP3RX->P3RXDepthMode.Normalise = __PERMEDIA_ENABLE;
  401. pSoftP3RX->P3RXDepthMode.NonLinearZ = __PERMEDIA_DISABLE;
  402. #endif
  403. pSoftP3RX->P3RXDepthMode.ExponentScale = 2;
  404. pSoftP3RX->P3RXDepthMode.ExponentWidth = 1;
  405. // Only setup to write to the chip after the above call, as
  406. // we may upset the DMA buffer setup.
  407. P3_DMA_GET_BUFFER_ENTRIES(20);
  408. // Window Region data
  409. SEND_P3_DATA(FBSourceOffset, 0x0);
  410. // Write Masks
  411. SEND_P3_DATA(FBSoftwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
  412. SEND_P3_DATA(FBHardwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
  413. // Host out unit
  414. SEND_P3_DATA(FilterMode, __PERMEDIA_DISABLE);
  415. SEND_P3_DATA(StatisticMode, __PERMEDIA_DISABLE); // Disable Stats
  416. // Local Buffer
  417. SEND_P3_DATA(LBSourceOffset, 0);
  418. // Window setups
  419. SEND_P3_DATA(WindowOrigin, __GLINT_TOP_LEFT_WINDOW_ORIGIN);
  420. SEND_P3_DATA(FBWindowBase, 0x0);
  421. SEND_P3_DATA(RasterizerMode, 0);
  422. // Setup a step of -1, as this doesn't change very much
  423. SEND_P3_DATA(dY, 0xFFFF0000);
  424. P3_DMA_COMMIT_BUFFER();
  425. P3_DMA_GET_BUFFER_ENTRIES(16);
  426. // Stencil mode setup
  427. pSoftP3RX->P3RXStencilMode.StencilWidth = 0;
  428. pSoftP3RX->P3RXStencilMode.DPFail = __GLINT_STENCIL_METHOD_KEEP;
  429. pSoftP3RX->P3RXStencilMode.DPPass = __GLINT_STENCIL_METHOD_KEEP;
  430. pSoftP3RX->P3RXStencilMode.Enable = __PERMEDIA_DISABLE;
  431. COPY_P3_DATA(StencilMode, pSoftP3RX->P3RXStencilMode);
  432. pSoftP3RX->P3RXFogMode.Enable = __PERMEDIA_ENABLE; // Qualified by the render command
  433. pSoftP3RX->P3RXFogMode.ColorMode = P3RX_FOGMODE_COLORMODE_RGB; // RGBA
  434. pSoftP3RX->P3RXFogMode.Table = __PERMEDIA_DISABLE;
  435. pSoftP3RX->P3RXFogMode.UseZ = __PERMEDIA_DISABLE;
  436. pSoftP3RX->P3RXFogMode.ZShift = 23; // Take the top 8 bits of the z value
  437. pSoftP3RX->P3RXFogMode.InvertFI = __PERMEDIA_DISABLE;
  438. DIRTY_FOG(pContext);
  439. pSoftP3RX->P3RXWindow.Enable = __PERMEDIA_DISABLE;
  440. pSoftP3RX->P3RXWindow.CompareMode = 0;
  441. pSoftP3RX->P3RXWindow.ForceLBUpdate = 0;
  442. pSoftP3RX->P3RXWindow.LBUpdateSource = 0;
  443. pSoftP3RX->P3RXWindow.GID = 0;
  444. pSoftP3RX->P3RXWindow.FrameCount = 0;
  445. pSoftP3RX->P3RXWindow.StencilFCP = 0;
  446. pSoftP3RX->P3RXWindow.DepthFCP = 0;
  447. COPY_P3_DATA(Window, pSoftP3RX->P3RXWindow);
  448. SEND_P3_DATA(ChromaUpper, 0x00000000);
  449. SEND_P3_DATA(ChromaLower, 0x00000000);
  450. // Use a black border for the bilinear filter.
  451. // This will only work for certain types of texture...
  452. SEND_P3_DATA(BorderColor0, 0x0);
  453. SEND_P3_DATA(BorderColor1, 0x0);
  454. // Alpha Test - later we'll DIRTY_EVERYTHING
  455. pSoftP3RX->P3RXAlphaTestMode.Enable = __PERMEDIA_DISABLE;
  456. pSoftP3RX->P3RXAlphaTestMode.Reference = 0x0;
  457. pSoftP3RX->P3RXAlphaTestMode.Compare = __GLINT_ALPHA_COMPARE_MODE_ALWAYS;
  458. SEND_P3_DATA(AreaStippleMode, (1 | (2 << 1) | (2 << 4)));
  459. pSoftP3RX->P3RX_P3DeltaMode.TargetChip = __PERMEDIA_ENABLE;
  460. pSoftP3RX->P3RX_P3DeltaMode.SpecularTextureEnable = __PERMEDIA_ENABLE;
  461. pSoftP3RX->P3RX_P3DeltaMode.TextureParameterMode = 2; // Normalise
  462. pSoftP3RX->P3RX_P3DeltaMode.TextureEnable = __PERMEDIA_ENABLE;
  463. pSoftP3RX->P3RX_P3DeltaMode.DiffuseTextureEnable = __PERMEDIA_DISABLE;
  464. pSoftP3RX->P3RX_P3DeltaMode.SmoothShadingEnable = __PERMEDIA_ENABLE;
  465. pSoftP3RX->P3RX_P3DeltaMode.SubPixelCorrectionEnable = __PERMEDIA_ENABLE;
  466. pSoftP3RX->P3RX_P3DeltaMode.DiamondExit = __PERMEDIA_ENABLE;
  467. #if 1
  468. pSoftP3RX->P3RX_P3DeltaMode.NoDraw = __PERMEDIA_DISABLE;
  469. #else
  470. pSoftP3RX->P3RX_P3DeltaMode.NoDraw = __PERMEDIA_ENABLE;
  471. #endif
  472. pSoftP3RX->P3RX_P3DeltaMode.ClampEnable = __PERMEDIA_ENABLE;
  473. pSoftP3RX->P3RX_P3DeltaMode.FillDirection = __PERMEDIA_DISABLE;
  474. pSoftP3RX->P3RX_P3DeltaMode.DepthFormat = 3; // Always 32 bits
  475. pSoftP3RX->P3RX_P3DeltaMode.ColorOrder = COLOR_MODE;
  476. pSoftP3RX->P3RX_P3DeltaMode.BiasCoordinates = __PERMEDIA_ENABLE;
  477. pSoftP3RX->P3RX_P3DeltaMode.Texture3DEnable = __PERMEDIA_DISABLE; // Always perspective correct (q is 1 otherwise)
  478. pSoftP3RX->P3RX_P3DeltaMode.TextureEnable1 = __PERMEDIA_DISABLE;
  479. pSoftP3RX->P3RX_P3DeltaMode.DepthEnable = __PERMEDIA_ENABLE;
  480. COPY_P3_DATA(DeltaMode, pSoftP3RX->P3RX_P3DeltaMode);
  481. P3_DMA_COMMIT_BUFFER();
  482. P3_DMA_GET_BUFFER_ENTRIES(18);
  483. {
  484. float ZBias;
  485. pContext->XBias = 0.5f;
  486. pContext->YBias = 0.5f;
  487. ZBias = 0.0f;
  488. SEND_P3_DATA(XBias, *(DWORD*)&pContext->XBias);
  489. SEND_P3_DATA(YBias, *(DWORD*)&pContext->YBias);
  490. SEND_P3_DATA(ZBias, *(DWORD*)&ZBias);
  491. }
  492. pSoftP3RX->P3RX_P3DeltaControl.FullScreenAA = __PERMEDIA_DISABLE;
  493. pSoftP3RX->P3RX_P3DeltaControl.DrawLineEndPoint = __PERMEDIA_DISABLE;
  494. pSoftP3RX->P3RX_P3DeltaControl.UseProvokingVertex = __PERMEDIA_DISABLE;
  495. COPY_P3_DATA(DeltaControl, pSoftP3RX->P3RX_P3DeltaControl);
  496. pSoftP3RX->P3RXTextureCoordMode.Enable = __PERMEDIA_ENABLE;
  497. pSoftP3RX->P3RXTextureCoordMode.WrapS = __GLINT_TEXADDRESS_WRAP_REPEAT;
  498. pSoftP3RX->P3RXTextureCoordMode.WrapT = __GLINT_TEXADDRESS_WRAP_REPEAT;
  499. pSoftP3RX->P3RXTextureCoordMode.Operation = __GLINT_TEXADDRESS_OPERATION_3D; // Perspective correct
  500. pSoftP3RX->P3RXTextureCoordMode.InhibitDDAInitialisation = __PERMEDIA_DISABLE;
  501. pSoftP3RX->P3RXTextureCoordMode.EnableLOD = __PERMEDIA_DISABLE;
  502. pSoftP3RX->P3RXTextureCoordMode.EnableDY = __PERMEDIA_DISABLE;
  503. pSoftP3RX->P3RXTextureCoordMode.TextureMapType = __GLINT_TEXADDRESS_TEXMAP_2D; // Always 2D
  504. pSoftP3RX->P3RXTextureCoordMode.DuplicateCoord = __PERMEDIA_DISABLE;
  505. COPY_P3_DATA(TextureCoordMode, pSoftP3RX->P3RXTextureCoordMode);
  506. pSoftP3RX->P3RXTextureReadMode0.Enable = __PERMEDIA_DISABLE;
  507. pSoftP3RX->P3RXTextureReadMode0.Width = log2(256);
  508. pSoftP3RX->P3RXTextureReadMode0.Height = log2(256);
  509. pSoftP3RX->P3RXTextureReadMode0.TexelSize = P3RX_TEXREADMODE_TEXELSIZE_16; // Pixel depth
  510. pSoftP3RX->P3RXTextureReadMode0.Texture3D = __PERMEDIA_DISABLE; // 3D Texture coordinates
  511. pSoftP3RX->P3RXTextureReadMode0.CombineCaches = __PERMEDIA_DISABLE;
  512. pSoftP3RX->P3RXTextureReadMode0.MapBaseLevel = 0;
  513. pSoftP3RX->P3RXTextureReadMode0.MapMaxLevel = 0;
  514. pSoftP3RX->P3RXTextureReadMode0.LogicalTexture = 0;
  515. pSoftP3RX->P3RXTextureReadMode0.Origin = __GLINT_TOP_LEFT_WINDOW_ORIGIN;
  516. pSoftP3RX->P3RXTextureReadMode0.TextureType = P3RX_TEXREADMODE_TEXTURETYPE_NORMAL;
  517. pSoftP3RX->P3RXTextureReadMode0.ByteSwap = __PERMEDIA_DISABLE;
  518. pSoftP3RX->P3RXTextureReadMode0.Mirror = __PERMEDIA_DISABLE;
  519. pSoftP3RX->P3RXTextureReadMode0.Invert = __PERMEDIA_DISABLE;
  520. pSoftP3RX->P3RXTextureReadMode0.OpaqueSpan = __PERMEDIA_DISABLE;
  521. COPY_P3_DATA(TextureReadMode0, pSoftP3RX->P3RXTextureReadMode0);
  522. pSoftP3RX->P3RXTextureReadMode1.Enable = __PERMEDIA_DISABLE;
  523. pSoftP3RX->P3RXTextureReadMode1.Width = log2(256);
  524. pSoftP3RX->P3RXTextureReadMode1.Height = log2(256);
  525. pSoftP3RX->P3RXTextureReadMode1.TexelSize = P3RX_TEXREADMODE_TEXELSIZE_16; // Pixel depth
  526. pSoftP3RX->P3RXTextureReadMode1.Texture3D = __PERMEDIA_DISABLE; // 3D Texture coordinates
  527. pSoftP3RX->P3RXTextureReadMode1.CombineCaches = __PERMEDIA_DISABLE;
  528. pSoftP3RX->P3RXTextureReadMode1.MapBaseLevel = 0;
  529. pSoftP3RX->P3RXTextureReadMode1.MapMaxLevel = 0;
  530. pSoftP3RX->P3RXTextureReadMode1.LogicalTexture = 0;
  531. pSoftP3RX->P3RXTextureReadMode1.Origin = __GLINT_TOP_LEFT_WINDOW_ORIGIN;
  532. pSoftP3RX->P3RXTextureReadMode1.TextureType = P3RX_TEXREADMODE_TEXTURETYPE_NORMAL;
  533. pSoftP3RX->P3RXTextureReadMode1.ByteSwap = __PERMEDIA_DISABLE;
  534. pSoftP3RX->P3RXTextureReadMode1.Mirror = __PERMEDIA_DISABLE;
  535. pSoftP3RX->P3RXTextureReadMode1.Invert = __PERMEDIA_DISABLE;
  536. pSoftP3RX->P3RXTextureReadMode1.OpaqueSpan = __PERMEDIA_DISABLE;
  537. COPY_P3_DATA(TextureReadMode1, pSoftP3RX->P3RXTextureReadMode1);
  538. pSoftP3RX->P3RXTextureIndexMode0.Enable = __PERMEDIA_DISABLE;
  539. pSoftP3RX->P3RXTextureIndexMode0.Width = log2(256);
  540. pSoftP3RX->P3RXTextureIndexMode0.Height = log2(256);
  541. pSoftP3RX->P3RXTextureIndexMode0.Border = __PERMEDIA_DISABLE;
  542. pSoftP3RX->P3RXTextureIndexMode0.WrapU = P3RX_TEXINDEXMODE_WRAP_CLAMPEDGE;
  543. pSoftP3RX->P3RXTextureIndexMode0.WrapV = P3RX_TEXINDEXMODE_WRAP_CLAMPEDGE;
  544. pSoftP3RX->P3RXTextureIndexMode0.MapType = __GLINT_TEXADDRESS_TEXMAP_2D;
  545. pSoftP3RX->P3RXTextureIndexMode0.MagnificationFilter = __GLINT_TEXTUREREAD_FILTER_NEAREST;
  546. pSoftP3RX->P3RXTextureIndexMode0.MinificationFilter = __GLINT_TEXTUREREAD_FILTER_NEAREST;
  547. pSoftP3RX->P3RXTextureIndexMode0.Texture3DEnable = __PERMEDIA_DISABLE;
  548. pSoftP3RX->P3RXTextureIndexMode0.MipMapEnable = __PERMEDIA_DISABLE;
  549. pSoftP3RX->P3RXTextureIndexMode0.NearestBias = 1;
  550. pSoftP3RX->P3RXTextureIndexMode0.LinearBias = 0;
  551. pSoftP3RX->P3RXTextureIndexMode0.SourceTexelEnable = __PERMEDIA_DISABLE;
  552. COPY_P3_DATA(TextureIndexMode0, pSoftP3RX->P3RXTextureIndexMode0);
  553. pSoftP3RX->P3RXTextureIndexMode1.Enable = __PERMEDIA_DISABLE;
  554. pSoftP3RX->P3RXTextureIndexMode1.Width = log2(256);
  555. pSoftP3RX->P3RXTextureIndexMode1.Height = log2(256);
  556. pSoftP3RX->P3RXTextureIndexMode1.Border = __PERMEDIA_DISABLE;
  557. pSoftP3RX->P3RXTextureIndexMode1.WrapU = P3RX_TEXINDEXMODE_WRAP_CLAMPEDGE;
  558. pSoftP3RX->P3RXTextureIndexMode1.WrapV = P3RX_TEXINDEXMODE_WRAP_CLAMPEDGE;
  559. pSoftP3RX->P3RXTextureIndexMode1.MapType = __GLINT_TEXADDRESS_TEXMAP_2D;
  560. pSoftP3RX->P3RXTextureIndexMode1.MagnificationFilter = __GLINT_TEXTUREREAD_FILTER_NEAREST;
  561. pSoftP3RX->P3RXTextureIndexMode1.MinificationFilter = __GLINT_TEXTUREREAD_FILTER_NEAREST;
  562. pSoftP3RX->P3RXTextureIndexMode1.Texture3DEnable = __PERMEDIA_DISABLE;
  563. pSoftP3RX->P3RXTextureIndexMode1.MipMapEnable = __PERMEDIA_DISABLE;
  564. pSoftP3RX->P3RXTextureIndexMode1.NearestBias = 1;
  565. pSoftP3RX->P3RXTextureIndexMode1.LinearBias = 0;
  566. pSoftP3RX->P3RXTextureIndexMode1.SourceTexelEnable = __PERMEDIA_DISABLE;
  567. COPY_P3_DATA(TextureIndexMode1, pSoftP3RX->P3RXTextureIndexMode1);
  568. pSoftP3RX->P3RXTextureCompositeColorMode0.Enable = 0;
  569. pSoftP3RX->P3RXTextureCompositeColorMode0.Scale = 1;
  570. pSoftP3RX->P3RXTextureCompositeColorMode1.Enable = 0;
  571. pSoftP3RX->P3RXTextureCompositeColorMode1.Scale = 1;
  572. pSoftP3RX->P3RXTextureCompositeAlphaMode0.Enable = 0;
  573. pSoftP3RX->P3RXTextureCompositeAlphaMode0.Scale = 1;
  574. pSoftP3RX->P3RXTextureCompositeAlphaMode1.Enable = 0;
  575. pSoftP3RX->P3RXTextureCompositeAlphaMode1.Scale = 1;
  576. P3_DMA_COMMIT_BUFFER();
  577. P3_DMA_GET_BUFFER_ENTRIES(16);
  578. COPY_P3_DATA(TextureCompositeColorMode0, pSoftP3RX->P3RXTextureCompositeColorMode0);
  579. COPY_P3_DATA(TextureCompositeColorMode1, pSoftP3RX->P3RXTextureCompositeColorMode1);
  580. COPY_P3_DATA(TextureCompositeAlphaMode0, pSoftP3RX->P3RXTextureCompositeAlphaMode0);
  581. COPY_P3_DATA(TextureCompositeAlphaMode1, pSoftP3RX->P3RXTextureCompositeAlphaMode1);
  582. // Set up the TC TFACTOR defaults.
  583. SEND_P3_DATA(TextureCompositeFactor0, 0);
  584. SEND_P3_DATA(TextureCompositeFactor1, 0);
  585. SEND_P3_DATA(TextureCacheReplacementMode, 0 );
  586. P3_DMA_COMMIT_BUFFER();
  587. P3_DMA_GET_BUFFER_ENTRIES(24);
  588. // Used for 3D Texture-maps
  589. SEND_P3_DATA(TextureMapSize, 0);
  590. SEND_P3_DATA(TextureLODBiasS, 0);
  591. SEND_P3_DATA(TextureLODBiasT, 0);
  592. {
  593. float f = 1.0f;
  594. COPY_P3_DATA(TextureLODScale, f);
  595. COPY_P3_DATA(TextureLODScale1, f);
  596. }
  597. P3RX_INVALIDATECACHE(__PERMEDIA_ENABLE, __PERMEDIA_ENABLE);
  598. pSoftP3RX->P3RXTextureApplicationMode.Enable = __PERMEDIA_ENABLE;
  599. pSoftP3RX->P3RXTextureApplicationMode.EnableKs = __PERMEDIA_DISABLE;
  600. pSoftP3RX->P3RXTextureApplicationMode.EnableKd = __PERMEDIA_DISABLE;
  601. pSoftP3RX->P3RXTextureApplicationMode.MotionCompEnable = __PERMEDIA_DISABLE;
  602. // Put the texture application unit in pass-through
  603. pSoftP3RX->P3RXTextureApplicationMode.ColorA = 0;
  604. pSoftP3RX->P3RXTextureApplicationMode.ColorB = P3RX_TEXAPP_B_TC;
  605. pSoftP3RX->P3RXTextureApplicationMode.ColorI = 0;
  606. pSoftP3RX->P3RXTextureApplicationMode.ColorInvertI = 0;
  607. pSoftP3RX->P3RXTextureApplicationMode.ColorOperation = P3RX_TEXAPP_OPERATION_PASS_B;
  608. pSoftP3RX->P3RXTextureApplicationMode.AlphaA = 0;
  609. pSoftP3RX->P3RXTextureApplicationMode.AlphaB = P3RX_TEXAPP_B_TA;
  610. pSoftP3RX->P3RXTextureApplicationMode.AlphaI = 0;
  611. pSoftP3RX->P3RXTextureApplicationMode.AlphaInvertI = 0;
  612. pSoftP3RX->P3RXTextureApplicationMode.AlphaOperation = P3RX_TEXAPP_OPERATION_PASS_B;
  613. COPY_P3_DATA(TextureApplicationMode, pSoftP3RX->P3RXTextureApplicationMode);
  614. // Set up the TA TFACTOR default.
  615. SEND_P3_DATA(TextureEnvColor, 0);
  616. // Turn on texture cache and invalidate it.
  617. SEND_P3_DATA(TextureCacheControl, 3);
  618. P3_DMA_COMMIT_BUFFER();
  619. P3_DMA_GET_BUFFER_ENTRIES(16);
  620. //pGlint->TextureMask = 0;
  621. SEND_P3_DATA(TextureBaseAddr0, 0);
  622. SEND_P3_DATA(TextureBaseAddr1, 0);
  623. pSoftP3RX->P3RXChromaTestMode.Enable = __PERMEDIA_DISABLE;
  624. pSoftP3RX->P3RXChromaTestMode.Source = __GLINT_CHROMA_FBSOURCE ;
  625. COPY_P3_DATA(ChromaTestMode, pSoftP3RX->P3RXChromaTestMode);
  626. pSoftP3RX->P3RXTextureFilterMode.Enable = __PERMEDIA_ENABLE;
  627. pSoftP3RX->P3RXTextureFilterMode.Format0 = 0;
  628. pSoftP3RX->P3RXTextureFilterMode.ColorOrder0 = COLOR_MODE;
  629. pSoftP3RX->P3RXTextureFilterMode.AlphaMapEnable0 = __PERMEDIA_DISABLE;
  630. pSoftP3RX->P3RXTextureFilterMode.AlphaMapSense0 = __GLINT_TEXTUREFILTER_ALPHAMAPSENSE_EXCLUDE;
  631. pSoftP3RX->P3RXTextureFilterMode.CombineCaches = __PERMEDIA_DISABLE;
  632. pSoftP3RX->P3RXTextureFilterMode.Format1 = 0;
  633. pSoftP3RX->P3RXTextureFilterMode.ColorOrder1 = COLOR_MODE;
  634. pSoftP3RX->P3RXTextureFilterMode.AlphaMapEnable1 = __PERMEDIA_DISABLE;
  635. pSoftP3RX->P3RXTextureFilterMode.AlphaMapSense1 = __GLINT_TEXTUREFILTER_ALPHAMAPSENSE_EXCLUDE;
  636. COPY_P3_DATA(TextureFilterMode, pSoftP3RX->P3RXTextureFilterMode);
  637. pSoftP3RX->P3RXLUTMode.Enable = __PERMEDIA_DISABLE;
  638. pSoftP3RX->P3RXLUTMode.InColorOrder = P3RX_LUTMODE_INCOLORORDER_BGR;
  639. pSoftP3RX->P3RXLUTMode.LoadFormat = P3RX_LUTMODE_LOADFORMAT_COPY;
  640. pSoftP3RX->P3RXLUTMode.LoadColorOrder = P3RX_LUTMODE_LOADCOLORORDER_RGB;
  641. pSoftP3RX->P3RXLUTMode.FragmentOperation = P3RX_LUTMODE_FRAGMENTOP_INDEXEDTEXTURE;
  642. COPY_P3_DATA(LUTMode, pSoftP3RX->P3RXLUTMode);
  643. pSoftP3RX->P3RXRasterizerMode.D3DRules = __PERMEDIA_ENABLE;
  644. pSoftP3RX->P3RXRasterizerMode.MultiRXBlit = __PERMEDIA_DISABLE;
  645. pSoftP3RX->P3RXRasterizerMode.OpaqueSpan = __PERMEDIA_DISABLE;
  646. pSoftP3RX->P3RXRasterizerMode.WordPacking = __PERMEDIA_DISABLE;
  647. pSoftP3RX->P3RXRasterizerMode.StripeHeight = 0;
  648. pSoftP3RX->P3RXRasterizerMode.BitMaskRelative = __PERMEDIA_DISABLE;
  649. pSoftP3RX->P3RXRasterizerMode.YLimitsEnable = __PERMEDIA_DISABLE;
  650. pSoftP3RX->P3RXRasterizerMode.MultiGLINT = __PERMEDIA_ENABLE;
  651. pSoftP3RX->P3RXRasterizerMode.HostDataByteSwapMode = 0;
  652. pSoftP3RX->P3RXRasterizerMode.BitMaskOffset = 0;
  653. pSoftP3RX->P3RXRasterizerMode.BitMaskPacking = __PERMEDIA_DISABLE;
  654. pSoftP3RX->P3RXRasterizerMode.BitMaskByteSwapMode = 0;
  655. pSoftP3RX->P3RXRasterizerMode.ForceBackgroundColor = __PERMEDIA_DISABLE;
  656. pSoftP3RX->P3RXRasterizerMode.BiasCoordinates = 0;
  657. pSoftP3RX->P3RXRasterizerMode.FractionAdjust = 0;
  658. pSoftP3RX->P3RXRasterizerMode.InvertBitMask = __PERMEDIA_DISABLE;
  659. pSoftP3RX->P3RXRasterizerMode.MirrorBitMask = __PERMEDIA_DISABLE;
  660. COPY_P3_DATA(RasterizerMode, pSoftP3RX->P3RXRasterizerMode);
  661. pSoftP3RX->P3RXScanlineOwnership.Mask = 0;
  662. pSoftP3RX->P3RXScanlineOwnership.MyId = 0;
  663. COPY_P3_DATA(ScanlineOwnership, pSoftP3RX->P3RXScanlineOwnership);
  664. P3_DMA_COMMIT_BUFFER();
  665. } // __CTX_Perm3_SetupD3D_HWDefaults
  666. //-----------------------------------------------------------------------------
  667. //
  668. // __CTX_SetupD3DContext_Defaults
  669. //
  670. // Initializes our private D3D context data (renderstates, TSS and other).
  671. //
  672. //-----------------------------------------------------------------------------
  673. void
  674. __CTX_SetupD3DContext_Defaults(
  675. P3_D3DCONTEXT* pContext)
  676. {
  677. DWORD dwStageNum;
  678. // Set all the stages to 'unused' and disabled
  679. for (dwStageNum = 0; dwStageNum < D3DHAL_TSS_MAXSTAGES; dwStageNum++)
  680. {
  681. pContext->iTexStage[dwStageNum] = -1;
  682. pContext->TextureStageState[dwStageNum].m_dwVal[D3DTSS_COLOROP] =
  683. D3DTOP_DISABLE;
  684. }
  685. // No texture at present.
  686. pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_COLOROP] = D3DTOP_DISABLE;
  687. pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_ALPHAOP] = D3DTOP_DISABLE;
  688. pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_TEXTUREMAP] = 0;
  689. pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_TEXTUREMAP] = 0;
  690. pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_MINFILTER] = D3DTFN_POINT;
  691. pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_MINFILTER] = D3DTFN_POINT;
  692. pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_MIPFILTER] = D3DTFN_POINT;
  693. pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_MIPFILTER] = D3DTFN_POINT;
  694. pContext->TextureStageState[TEXSTAGE_0].m_dwVal[D3DTSS_MAGFILTER] = D3DTFN_POINT;
  695. pContext->TextureStageState[TEXSTAGE_1].m_dwVal[D3DTSS_MAGFILTER] = D3DTFN_POINT;
  696. pContext->eChipBlendStatus = BSF_UNINITIALISED;
  697. // Initially set values to force change of texture
  698. pContext->bTextureValid = TRUE;
  699. // Defaults states
  700. pContext->RenderStates[D3DRENDERSTATE_TEXTUREMAPBLEND] = D3DTBLEND_COPY;
  701. pContext->fRenderStates[D3DRENDERSTATE_FOGTABLESTART] = 0.0f;
  702. pContext->fRenderStates[D3DRENDERSTATE_FOGTABLEEND] = 1.0f;
  703. pContext->RenderStates[D3DRENDERSTATE_CULLMODE] = D3DCULL_CCW;
  704. pContext->RenderStates[D3DRENDERSTATE_PLANEMASK] = 0xFFFFFFFF;
  705. pContext->RenderStates[D3DRENDERSTATE_LOCALVIEWER] = FALSE;
  706. pContext->RenderStates[D3DRENDERSTATE_COLORKEYENABLE] = FALSE;
  707. #if DX8_DDI
  708. // New DX8 D3DRS_COLORWRITEENABLE default = allow write to all channels
  709. pContext->dwColorWriteHWMask = 0xFFFFFFFF;
  710. pContext->dwColorWriteSWMask = 0xFFFFFFFF;
  711. #endif //DX8_DDI
  712. // On context creation, no render states are overridden (for legacy intfce's)
  713. STATESET_INIT(pContext->overrides);
  714. // Set default culling state
  715. SET_CULLING_TO_CCW(pContext);
  716. #if DX7_D3DSTATEBLOCKS
  717. // Default state block recording mode = no recording
  718. pContext->bStateRecMode = FALSE;
  719. pContext->pCurrSS = NULL;
  720. pContext->pIndexTableSS = NULL;
  721. pContext->dwMaxSSIndex = 0;
  722. #endif //DX7_D3DSTATEBLOCKS
  723. #if DX8_POINTSPRITES
  724. // Point sprite defaults
  725. pContext->PntSprite.bEnabled = FALSE;
  726. pContext->PntSprite.fSize = 1.0f;
  727. pContext->PntSprite.fSizeMin = 1.0f;
  728. pContext->PntSprite.fSizeMax = P3_MAX_POINTSPRITE_SIZE;
  729. #endif //DX8_POINTSPRITES
  730. // Multistreaming default setup
  731. pContext->lpVertices = NULL;
  732. pContext->dwVertexType = 0;
  733. #if DX8_DDI
  734. pContext->lpIndices = NULL;
  735. pContext->dwIndicesStride = 0;
  736. pContext->dwVerticesStride = 0;
  737. #endif // DX8_DDI
  738. //*********************************
  739. // INTERNAL CONTEXT RENDERING STATE
  740. //*********************************
  741. pContext->bKeptStipple = FALSE; // By default, stippling off.
  742. pContext->bCanChromaKey = FALSE; // Turn Chroma keying off by default
  743. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  744. pContext->dwAliasPixelOffset = 0x0;
  745. pContext->dwAliasZPixelOffset = 0x0;
  746. pContext->dwAliasZBuffer = 0x0;
  747. pContext->dwAliasBackBuffer = 0x0;
  748. #if DX8_DDI
  749. if (pContext->pSurfRenderInt->dwSampling)
  750. {
  751. pContext->RenderStates[D3DRS_MULTISAMPLEANTIALIAS] = TRUE;
  752. pContext->Flags |= SURFACE_ANTIALIAS;
  753. }
  754. #endif
  755. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  756. // Set texturing on
  757. pContext->Flags |= SURFACE_TEXTURING;
  758. // Initialize the mipmap bias
  759. pContext->MipMapLODBias[0] = 0.0f;
  760. pContext->MipMapLODBias[1] = 0.0f;
  761. // Initialise the RenderCommand. States will add to this
  762. pContext->RenderCommand = 0;
  763. RENDER_SUB_PIXEL_CORRECTION_ENABLE(pContext->RenderCommand);
  764. // Dirty all states
  765. DIRTY_EVERYTHING(pContext);
  766. } // __CTX_SetupD3DContext_Defaults
  767. //-----------------------------------------------------------------------------
  768. // ****************************************************************************
  769. // ***************************** D3D HAL Callbacks ****************************
  770. // ****************************************************************************
  771. //-----------------------------------------------------------------------------
  772. //-----------------------------Public Routine----------------------------------
  773. //
  774. // D3DContextCreate
  775. //
  776. // The ContextCreate callback is invoked when a new Direct3D device is being
  777. // created by a Direct3D application. The driver is required to generate a
  778. // unique context id for this new context. Direct3D will then use this context
  779. // id in every subsequent callback invocation for this Direct3D device.
  780. //
  781. // Context is the current rasterization state. For instance, if there are 3
  782. // applications running, each will have a different state at any point in time.
  783. // When each one is running, the hardware has to make sure that the context,
  784. // (whether doing Gouraud shading, for example) is the same as the last time
  785. // that application got a time slice.
  786. //
  787. // State is anything that the particular device needs to know per context
  788. // i.e. what surface is being rendered to, shading, texture, texture handles,
  789. // what physical surfaces those texture handles represent, etc. The context
  790. // encapsulates all state for the Direct3D device - state is not shared
  791. // between contexts. Therefore the driver needs to maintain full state
  792. // information for each context. This state will be changed by calls to the
  793. // RenderState callback. In the case of rasterization only hardware, the
  794. // driver need only maintain rasterization state. As well as state, the driver
  795. // will also want to store the lpDDS, lpDDSZ, and dwPid from the callback
  796. // data argument.
  797. //
  798. // The driver should not create a context handle of zero. This is guaranteed
  799. // to be an invalid context handle.
  800. //
  801. // Parameters
  802. // pccd
  803. // Pointer to a structure containing things including the current
  804. // rendering surface, the current Z surface, and the DirectX object
  805. // handle, etc.
  806. //
  807. // .lpDDGbl
  808. // Points to the DirectDraw structure representing the
  809. // DirectDraw object.
  810. // .lpDDLcl(replaces lpDDGbl in DX7)
  811. // Points to the DirectDraw structure representing the
  812. // DirectDraw object.
  813. // .lpDDS
  814. // This is the surface that is to be used as the rendering
  815. // target, i.e., the 3D accelerator sprays its bits at this
  816. // surface.
  817. // .lpDDSZ
  818. // The surface that is to be used as the Z buffer. If this
  819. // is NULL, no Z buffering is to be performed.
  820. // .dwPid
  821. // The process id of the Direct3D application that initiated
  822. // the creation of the Direct3D device.
  823. // .dwhContext
  824. // The driver should place the context ID that it wants Direct3D
  825. // to use when communicating with the driver. This should be
  826. // unique.
  827. // .ddrval
  828. // Return code. DD_OK indicates success.
  829. //
  830. // Return Value
  831. // Returns one of the following values:
  832. // DDHAL_DRIVER_HANDLED
  833. // DDHAL_DRIVER_NOTHANDLED
  834. //
  835. // Notes:
  836. //
  837. // Currently the context isn't locked, so we can't switch in a register context.
  838. // All chip specific setup is therefore saved for the first execute.
  839. // This is guaranteed to have the lock.
  840. // Some chip state is duplicated in the context structure. This
  841. // means that a software copy is kept to stop unnecessary changes to
  842. // the chip state.
  843. //
  844. //-----------------------------------------------------------------------------
  845. DWORD CALLBACK
  846. D3DContextCreate(
  847. LPD3DHAL_CONTEXTCREATEDATA pccd)
  848. {
  849. LPDDRAWI_DDRAWSURFACE_LCL lpLclFrame = NULL;
  850. LPDDRAWI_DDRAWSURFACE_LCL lpLclZ = NULL;
  851. P3_D3DCONTEXT *pContext;
  852. P3_THUNKEDDATA *pThisDisplay;
  853. DWORD Result;
  854. DWORD dwSlotNum;
  855. ULONG_PTR dwDXInterface;
  856. BOOL bRet;
  857. DBG_CB_ENTRY(D3DContextCreate);
  858. // Get our pThisDisplay
  859. GET_THUNKEDDATA(pThisDisplay, pccd->lpDDLcl->lpGbl);
  860. //***********************************************************************
  861. // Create a new D3D context driver structure and asssociate an id with it
  862. //***********************************************************************
  863. // Find a context empty slot.
  864. dwSlotNum = __CTX_NewHandle();
  865. if (dwSlotNum == 0)
  866. {
  867. // no context slots left
  868. pccd->ddrval = D3DHAL_OUTOFCONTEXTS;
  869. DBG_CB_EXIT(D3DContextCreate,pccd->ddrval);
  870. return (DDHAL_DRIVER_HANDLED);
  871. }
  872. // Return to the runtime the D3D context id that will be used to
  873. // identify calls for this context from now on. Store prev value
  874. // since that tells us which API are we being called from
  875. // (4=DX8, 3=DX7, 2=DX6, 1=DX5, 0=DX3)
  876. dwDXInterface = pccd->dwhContext; // in: DX API version
  877. pccd->dwhContext = dwSlotNum; // out: Context handle
  878. // Now allocate the driver's d3d context structure in kernel memory.
  879. pContext = (P3_D3DCONTEXT*)HEAP_ALLOC(FL_ZERO_MEMORY,
  880. sizeof(P3_D3DCONTEXT),
  881. ALLOC_TAG_DX(1));
  882. if (pContext == NULL)
  883. {
  884. DISPDBG((ERRLVL,"ERROR: Couldn't allocate Context mem"));
  885. goto Error_OutOfMem_A;
  886. }
  887. else
  888. {
  889. DISPDBG((DBGLVL,"Allocated Context Mem - proceeding to clear"));
  890. memset((void *)pContext, 0, sizeof(P3_D3DCONTEXT));
  891. }
  892. // This context id is now to be associated with this context pointer
  893. __CTX_AssocPtrToHandle(dwSlotNum, pContext);
  894. //*************************************************************************
  895. // Initialize the D3D context structure
  896. //*************************************************************************
  897. //*******
  898. // HEADER
  899. //*******
  900. // Set up the magic number to perform sanity checks
  901. pContext->MagicNo = RC_MAGIC_NO;
  902. // Record the usage of this context handle
  903. pContext->dwContextHandle = dwSlotNum;
  904. // Keep (self) pointers to the structure for destroy time
  905. pContext->pSelf = pContext;
  906. #if DX8_DDI
  907. // Remember which DX interface is creating this context
  908. // - it will make things much easier later
  909. pContext->dwDXInterface = dwDXInterface;
  910. #endif // DX8_DDI
  911. //**********************
  912. // GLOBAL DRIVER CONTEXT
  913. //**********************
  914. // Remember the card we are running on
  915. pContext->pThisDisplay = pThisDisplay;
  916. // On DX7 we need to keep a copy of the local ddraw object
  917. // for surface handle management
  918. pContext->pDDLcl = pccd->lpDDLcl;
  919. pContext->pDDGbl = pccd->lpDDLcl->lpGbl;
  920. //*******************
  921. // RENDERING SURFACES
  922. //*******************
  923. // On DX7 we extract the local surface pointers directly
  924. lpLclFrame = pccd->lpDDSLcl;
  925. if (pccd->lpDDSZ)
  926. {
  927. lpLclZ = pccd->lpDDSZLcl;
  928. }
  929. #if DBG
  930. // Spew debug rendering surfaces data on the debug build
  931. DISPDBG((DBGLVL,"Allocated Direct3D context: 0x%x",pccd->dwhContext));
  932. DISPDBG((DBGLVL,"Driver Struct = %p, Surface = %p",
  933. pContext->pDDGbl, lpLclFrame));
  934. DISPDBG((DBGLVL,"Z Surface = %p",lpLclZ));
  935. if ((DWORD*)lpLclZ != NULL)
  936. {
  937. DISPDBG((DBGLVL," ZlpGbl: %p", lpLclZ->lpGbl));
  938. DISPDBG((DBGLVL," fpVidMem = %08lx",lpLclZ->lpGbl->fpVidMem));
  939. DISPDBG((DBGLVL," lPitch = %08lx",lpLclZ->lpGbl->lPitch));
  940. DISPDBG((DBGLVL," wHeight = %08lx",lpLclZ->lpGbl->wHeight));
  941. DISPDBG((DBGLVL," wWidth = %08lx",lpLclZ->lpGbl->wWidth));
  942. }
  943. DISPDBG((DBGLVL,"Buffer Surface = %p",lpLclFrame));
  944. if ((DWORD*)lpLclFrame != NULL)
  945. {
  946. DISPDBG((DBGLVL," fpVidMem = %08lx",lpLclFrame->lpGbl->fpVidMem));
  947. DISPDBG((DBGLVL," lPitch = %08lx",lpLclFrame->lpGbl->lPitch));
  948. DISPDBG((DBGLVL," wHeight = %08lx",lpLclFrame->lpGbl->wHeight));
  949. DISPDBG((DBGLVL," wWidth = %08lx",lpLclFrame->lpGbl->wWidth));
  950. }
  951. #endif // DBG
  952. #if DX7_TEXMANAGEMENT
  953. // Initialize texture management for this context
  954. if(FAILED(_D3D_TM_Ctx_Initialize(pContext)))
  955. {
  956. // We failed. Cleanup before we leave
  957. DISPDBG((ERRLVL,"ERROR: Couldn't initialize Texture Management"));
  958. goto Error_OutOfMem_B;
  959. }
  960. #endif // DX7_TEXMANAGEMENT
  961. // There may not have been any textures (DD surfaces) created yet through
  962. // D3DCreateSurfaceEx. If this is the case, create a new DD locals hash
  963. // entry and fill it will a pointer array
  964. pContext->pTexturePointerArray =
  965. (PointerArray*)HT_GetEntry(pThisDisplay->pDirectDrawLocalsHashTable,
  966. (ULONG_PTR)pContext->pDDLcl);
  967. if (!pContext->pTexturePointerArray)
  968. {
  969. DISPDBG((DBGLVL,"Creating new pointer array for PDDLcl "
  970. "0x%x in ContextCreate", pContext->pDDLcl));
  971. // Create a pointer array
  972. pContext->pTexturePointerArray = PA_CreateArray();
  973. if (!pContext->pTexturePointerArray)
  974. {
  975. // We ran out of memory. Cleanup before we leave
  976. DISPDBG((ERRLVL,"ERROR: Couldn't allocate Context mem "
  977. "for pTexturePointerArray"));
  978. goto Error_OutOfMem_B;
  979. }
  980. // It is an array of surfaces, so set the destroy callback
  981. PA_SetDataDestroyCallback(pContext->pTexturePointerArray,
  982. _D3D_SU_SurfaceArrayDestroyCallback);
  983. // Add this DD local to the hash table, and
  984. // store the texture pointer array
  985. if(!HT_AddEntry(pThisDisplay->pDirectDrawLocalsHashTable,
  986. (ULONG_PTR)pContext->pDDLcl,
  987. pContext->pTexturePointerArray))
  988. {
  989. // failed to add entry, noe cleanup and exit
  990. // We ran out of memory. Cleanup before we leave
  991. DISPDBG((ERRLVL,"ERROR: Couldn't allocate Context mem"));
  992. goto Error_OutOfMem_C;
  993. }
  994. }
  995. // Record the internal surface information
  996. pContext->pSurfRenderInt =
  997. GetSurfaceFromHandle(pContext,
  998. lpLclFrame->lpSurfMore->dwSurfaceHandle);
  999. if ( NULL == pContext->pSurfRenderInt)
  1000. {
  1001. // We ran out of memory when allocating for the rendertarget.
  1002. // Cleanup before we leave
  1003. DISPDBG((ERRLVL,"ERROR: Couldn't allocate pSurfRenderInt mem"));
  1004. goto Error_OutOfMem_D;
  1005. }
  1006. if (lpLclZ)
  1007. {
  1008. pContext->pSurfZBufferInt =
  1009. GetSurfaceFromHandle(pContext,
  1010. lpLclZ->lpSurfMore->dwSurfaceHandle);
  1011. if ( NULL == pContext->pSurfZBufferInt)
  1012. {
  1013. // We ran out of memory when allocating for the depth buffer.
  1014. // Cleanup before we leave
  1015. DISPDBG((ERRLVL,"ERROR: Couldn't allocate pSurfZBufferInt mem"));
  1016. goto Error_OutOfMem_D;
  1017. }
  1018. }
  1019. else
  1020. {
  1021. pContext->pSurfZBufferInt = NULL;
  1022. }
  1023. pContext->ModeChangeCount = pThisDisplay->ModeChangeCount;
  1024. //******************
  1025. // DEBUG USEFUL INFO
  1026. //******************
  1027. // Store the process id in which this d3d context was created
  1028. pContext->OwningProcess = pccd->dwPID;
  1029. // Depth of the primary surface
  1030. pContext->BPP = pContext->pThisDisplay->ddpfDisplay.dwRGBBitCount >> 3;
  1031. //******************************
  1032. // HW STATE FOR THIS D3D CONTEXT
  1033. //******************************
  1034. // Did we setup a DMA buffer at start of day, or FIFO's?
  1035. if (pThisDisplay->DMAInfo.dwBuffSize == 0)
  1036. {
  1037. DISPDBG((WRNLVL, "No DMA buffer available - using FIFO's for 3D"));
  1038. pContext->b3D_FIFOS = TRUE;
  1039. }
  1040. else
  1041. {
  1042. DISPDBG((WRNLVL, "Using shared DMA buffer"));
  1043. pContext->b3D_FIFOS = FALSE;
  1044. }
  1045. //************************************
  1046. // DEFAULT D3D OVERALL RENDERING STATE
  1047. //************************************
  1048. __CTX_SetupD3DContext_Defaults(pContext);
  1049. //*************************************************************************
  1050. // ACTUALLY SETUP HARDWARE IN ORDER TO USE THIS D3D CONTEXT
  1051. //*************************************************************************
  1052. STOP_SOFTWARE_CURSOR(pThisDisplay);
  1053. // Setup default states values to the chip
  1054. __CTX_Perm3_SetupD3D_HWDefaults(pContext);
  1055. // Find out info for screen size and depth
  1056. DISPDBG((DBGLVL, "ScreenWidth %d, ScreenHeight %d, Bytes/Pixel %d",
  1057. pContext->pThisDisplay->dwScreenWidth,
  1058. pContext->pThisDisplay->dwScreenHeight, pContext->BPP));
  1059. // Setup the relevent registers for the surfaces in use in this context.
  1060. if ( FAILED( _D3D_OP_SetRenderTarget(pContext,
  1061. pContext->pSurfRenderInt,
  1062. pContext->pSurfZBufferInt,
  1063. TRUE) ))
  1064. {
  1065. goto Error_OutOfMem_D;
  1066. }
  1067. // Process some defaults with which we initialize each D3D context
  1068. _D3D_ST_ProcessOneRenderState(pContext,
  1069. D3DRENDERSTATE_SHADEMODE,
  1070. D3DSHADE_GOURAUD);
  1071. _D3D_ST_ProcessOneRenderState(pContext,
  1072. D3DRENDERSTATE_FOGCOLOR,
  1073. 0xFFFFFFFF);
  1074. #if DX8_DDI
  1075. // On DX8 D3DRENDERSTATE_TEXTUREPERSPECTIVE has been retired and is assumed
  1076. // to be set always to TRUE. We must make sure we are setting the hw up
  1077. // correctly, so in order to do that we make an explicit setup call here
  1078. _D3D_ST_ProcessOneRenderState(pContext,
  1079. D3DRENDERSTATE_TEXTUREPERSPECTIVE,
  1080. 1);
  1081. #endif // DX8_DDI
  1082. #if DX7_PALETTETEXTURE
  1083. // Palette pointer array is per context, it is NOT associated with DD Local
  1084. pContext->pPalettePointerArray = PA_CreateArray();
  1085. if (! pContext->pPalettePointerArray)
  1086. {
  1087. // We ran out of memory. Cleanup before we leave
  1088. DISPDBG((ERRLVL,"ERROR: Couldn't allocate Context mem "
  1089. "for pPalettePointerArray"));
  1090. goto Error_OutOfMem_D;
  1091. }
  1092. // It is an array of surfaces, so set the destroy callback
  1093. PA_SetDataDestroyCallback(pContext->pTexturePointerArray,
  1094. _D3D_SU_PaletteArrayDestroyCallback);
  1095. #endif
  1096. START_SOFTWARE_CURSOR(pThisDisplay);
  1097. pccd->ddrval = DD_OK; // Call handled OK
  1098. DBG_CB_EXIT(D3DContextCreate,pccd->ddrval);
  1099. return (DDHAL_DRIVER_HANDLED);
  1100. //**************************************************************************
  1101. // ERROR HANDLING CODE PATHS
  1102. //**************************************************************************
  1103. Error_OutOfMem_D:
  1104. // Remove the texture pointer array from the hash table
  1105. HT_RemoveEntry(pThisDisplay->pDirectDrawLocalsHashTable,
  1106. (ULONG_PTR)pccd->lpDDLcl,
  1107. pThisDisplay);
  1108. goto Error_OutOfMem_B;
  1109. Error_OutOfMem_C:
  1110. // Free binding surface array (we'll no longer need it, and
  1111. // D3DCreateSurfaceEx will create a new one if necessary)
  1112. PA_DestroyArray(pContext->pTexturePointerArray, pThisDisplay);
  1113. Error_OutOfMem_B:
  1114. // Free D3D context data structure that we allocated
  1115. HEAP_FREE(pContext->pSelf);
  1116. Error_OutOfMem_A:
  1117. // Release the context handle (otherwise it will remain in use forever)
  1118. __CTX_HandleRelease((DWORD)pccd->dwhContext);
  1119. pccd->dwhContext = 0;
  1120. pccd->ddrval = DDERR_OUTOFMEMORY;
  1121. DBG_CB_EXIT(D3DContextCreate,pccd->ddrval);
  1122. return (DDHAL_DRIVER_HANDLED);
  1123. } // D3DContextCreate
  1124. //-----------------------------Public Routine----------------------------------
  1125. //
  1126. // D3DContextDestroy
  1127. //
  1128. // This callback is invoked when a Direct3D Device is being destroyed. As each
  1129. // device is represented by a context ID, the driver is passed a context to
  1130. // destroy.
  1131. //
  1132. // The driver should free all resources it allocated to the context being
  1133. // deleted. For example, the driver should free any texture resources it
  1134. // associated with the context. The driver should not free the DirectDraw
  1135. // surface(s) associated with the context because these will be freed by
  1136. // DirectDraw in response to an application or Direct3D runtime request.
  1137. //
  1138. // Parameters
  1139. // pcdd
  1140. // Pointer to Context destroy information.
  1141. //
  1142. // .dwhContext
  1143. // The ID of the context to be destroyed.
  1144. // .ddrval
  1145. // Return code. DD_OK indicates success.
  1146. //
  1147. // Return Value
  1148. // Returns one of the following values:
  1149. // DDHAL_DRIVER_HANDLED
  1150. // DDHAL_DRIVER_NOTHANDLED
  1151. //
  1152. //-----------------------------------------------------------------------------
  1153. DWORD CALLBACK
  1154. D3DContextDestroy(
  1155. LPD3DHAL_CONTEXTDESTROYDATA pccd)
  1156. {
  1157. P3_D3DCONTEXT *pContext;
  1158. P3_THUNKEDDATA *pThisDisplay;
  1159. DBG_CB_ENTRY(D3DContextDestroy);
  1160. // Deleting context
  1161. DISPDBG((DBGLVL,"D3DContextDestroy Context = %08lx",pccd->dwhContext));
  1162. pContext = _D3D_CTX_HandleToPtr(pccd->dwhContext);
  1163. if (!CHECK_D3DCONTEXT_VALIDITY(pContext))
  1164. {
  1165. pccd->ddrval = D3DHAL_CONTEXT_BAD;
  1166. DISPDBG((WRNLVL,"Context not valid"));
  1167. DBG_CB_EXIT(D3DContextDestroy,pccd->ddrval );
  1168. return (DDHAL_DRIVER_HANDLED);
  1169. }
  1170. pThisDisplay = pContext->pThisDisplay;
  1171. // Flush any DMA and Sync the chip so that that DMA can complete
  1172. // (deletecontexts aren't an every day occurance, so we may as well)
  1173. STOP_SOFTWARE_CURSOR(pThisDisplay);
  1174. #if WNT_DDRAW
  1175. if (pThisDisplay->ppdev->bEnabled)
  1176. {
  1177. #endif
  1178. DDRAW_OPERATION(pContext, pThisDisplay);
  1179. {
  1180. P3_DMA_DEFS();
  1181. P3_DMA_GET_BUFFER();
  1182. P3_DMA_FLUSH_BUFFER();
  1183. }
  1184. SYNC_WITH_GLINT;
  1185. #if WNT_DDRAW
  1186. }
  1187. #endif
  1188. START_SOFTWARE_CURSOR(pThisDisplay);
  1189. // Mark the context as disabled
  1190. pContext->MagicNo = RC_MAGIC_DISABLE;
  1191. #if DX7_TEXMANAGEMENT
  1192. // Cleanup any texture management stuff before leaving
  1193. _D3D_TM_Ctx_Destroy(pContext);
  1194. #endif // DX7_TEXMANAGEMENT
  1195. // Free and cleanup any associated hardware resources
  1196. __CTX_CleanDirect3DContext(pContext);
  1197. // Mark the context as now empty (dwhContext is ULONG_PTR for Win64)
  1198. __CTX_HandleRelease((DWORD)pccd->dwhContext);
  1199. // Finally, free up rendering context structure and set to NULL
  1200. HEAP_FREE(pContext->pSelf);
  1201. pContext = NULL;
  1202. pccd->ddrval = DD_OK;
  1203. DBG_CB_EXIT(D3DContextDestroy, pccd->ddrval);
  1204. return (DDHAL_DRIVER_HANDLED);
  1205. } // D3DContextDestroy