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.

1056 lines
35 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  4. * !! !!
  5. * !! WARNING: NOT DDK SAMPLE CODE !!
  6. * !! !!
  7. * !! This source code is provided for completeness only and should not be !!
  8. * !! used as sample code for display driver development. Only those sources !!
  9. * !! marked as sample code for a given driver component should be used for !!
  10. * !! development purposes. !!
  11. * !! !!
  12. * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  13. *
  14. * Module Name: hwcontxt.c
  15. *
  16. * Content: Manages hardware context switching between GDI/DD/D3D
  17. *
  18. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  19. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  20. \*****************************************************************************/
  21. #include "glint.h"
  22. #include "dma.h"
  23. #include "tag.h"
  24. //-----------------------------------------------------------------------------
  25. //
  26. // Driver Version
  27. //
  28. // This helps us find out from the debugger what driver is loaded on a given
  29. // remote system
  30. //
  31. //-----------------------------------------------------------------------------
  32. char gc_DriverVersion[] =
  33. #if DX8_DDI
  34. " DX8"
  35. #else
  36. " DX7"
  37. #endif
  38. #if DBG
  39. " CHECKED DRIVER"
  40. #else
  41. " FREE DRIVER"
  42. #endif
  43. " In Path: " __FILE__
  44. " Compiled on Date: " __DATE__
  45. " Time: " __TIME__
  46. " With #defines: "
  47. " DX8_MULTSTREAMS: "
  48. #if DX8_MULTSTREAMS
  49. "1"
  50. #else
  51. "0"
  52. #endif
  53. " DX8_VERTEXSHADERS: "
  54. #if DX8_VERTEXSHADERS
  55. "1"
  56. #else
  57. "0"
  58. #endif
  59. " DX8_POINTSPRITES: "
  60. #if DX8_POINTSPRITES
  61. "1"
  62. #else
  63. "0"
  64. #endif
  65. " DX8_PIXELSHADERS: "
  66. #if DX8_PIXELSHADERS
  67. "1"
  68. #else
  69. "0"
  70. #endif
  71. " DX8_3DTEXTURES: "
  72. #if DX8_3DTEXTURES
  73. "1"
  74. #else
  75. "0"
  76. #endif
  77. " DX8_MULTISAMPLING: "
  78. #if DX8_MULTISAMPLING
  79. "1"
  80. #else
  81. "0"
  82. #endif
  83. " DX7_ANTIALIAS: "
  84. #if DX7_ANTIALIAS
  85. "1"
  86. #else
  87. "0"
  88. #endif
  89. " DX7_D3DSTATEBLOCKS: "
  90. #if DX7_D3DSTATEBLOCKS
  91. "1"
  92. #else
  93. "0"
  94. #endif
  95. " DX7_PALETTETEXTURE: "
  96. #if DX7_PALETTETEXTURE
  97. "1"
  98. #else
  99. "0"
  100. #endif
  101. " DX7_STEREO: "
  102. #if DX7_STEREO
  103. "1"
  104. #else
  105. "0"
  106. #endif
  107. " DX7_TEXMANAGEMENT: "
  108. #if DX7_TEXMANAGEMENT
  109. "1"
  110. #else
  111. "0"
  112. #endif
  113. ;
  114. //-----------------------------------------------------------------------------
  115. //
  116. // __HWC_SwitchToDX
  117. //
  118. // Writes any hardware registers that need updating on entry into the
  119. // DirectX driver, which are appropriate to both DirectDraw and Direct3D.
  120. //
  121. //-----------------------------------------------------------------------------
  122. void __HWC_SwitchToDX( P3_THUNKEDDATA* pThisDisplay, BOOL bDXEntry)
  123. {
  124. P3_DMA_DEFS();
  125. P3_DMA_GET_BUFFER_ENTRIES(4);
  126. SEND_P3_DATA(SizeOfFramebuffer, pThisDisplay->pGLInfo->ddFBSize >> 4);
  127. // We have entered the DirectX driver from a
  128. // foreign context (such as the display driver)
  129. if (bDXEntry)
  130. {
  131. //@@BEGIN_DDKSPLIT
  132. #if DX7_VERTEXBUFFERS
  133. // First cause a flush of all buffers
  134. // We know this is safe because the contex switch
  135. // from the other driver to here will have caused a sync
  136. // and the buffers must therefore have been consumed
  137. // therefore we call with bWait == FALSE
  138. _D3D_EB_FlushAllBuffers(pThisDisplay, FALSE);
  139. #endif //DX7_VERTEXBUFFERS
  140. //@@END_DDKSPLIT
  141. // Reset the hostin ID
  142. SEND_P3_DATA(HostInID, 0);
  143. pThisDisplay->dwCurrentSequenceID = 0;
  144. }
  145. P3_DMA_COMMIT_BUFFER();
  146. if (bDXEntry)
  147. {
  148. P3_DMA_GET_BUFFER_ENTRIES( 4 );
  149. // Reset the RenderID to the last-used one.
  150. SEND_HOST_RENDER_ID ( GET_HOST_RENDER_ID() );
  151. P3_DMA_FLUSH_BUFFER();
  152. // Need to push the render ID to the end of the pipe...
  153. SYNC_WITH_GLINT;
  154. // ...and now it's valid.
  155. pThisDisplay->bRenderIDValid = (DWORD)TRUE;
  156. }
  157. } // __HWC_SwitchToDX
  158. //-----------------------------------------------------------------------------
  159. //
  160. // HWC_SwitchToDDRAW
  161. //
  162. // Writes any hardware registers that need updating on entry into the
  163. // DirectX driver, which are appropriate specifically to DirectDraw
  164. //
  165. //-----------------------------------------------------------------------------
  166. void HWC_SwitchToDDRAW( P3_THUNKEDDATA* pThisDisplay, BOOL bDXEntry)
  167. {
  168. P3_DMA_DEFS();
  169. __HWC_SwitchToDX(pThisDisplay, bDXEntry);
  170. P3_DMA_GET_BUFFER();
  171. P3_ENSURE_DX_SPACE(32);
  172. WAIT_FIFO(32);
  173. // Disable various units
  174. SEND_P3_DATA(AreaStippleMode, __PERMEDIA_DISABLE);
  175. SEND_P3_DATA(LineStippleMode, __PERMEDIA_DISABLE);
  176. SEND_P3_DATA(ScissorMode, __PERMEDIA_DISABLE);
  177. SEND_P3_DATA(ColorDDAMode, __PERMEDIA_DISABLE);
  178. SEND_P3_DATA(FogMode, __PERMEDIA_DISABLE);
  179. SEND_P3_DATA(AntialiasMode, __PERMEDIA_DISABLE);
  180. SEND_P3_DATA(AlphaTestMode, __PERMEDIA_DISABLE);
  181. SEND_P3_DATA(Window, __PERMEDIA_DISABLE);
  182. SEND_P3_DATA(StencilMode, __PERMEDIA_DISABLE);
  183. SEND_P3_DATA(DepthMode, __PERMEDIA_DISABLE);
  184. SEND_P3_DATA(DitherMode, __PERMEDIA_DISABLE);
  185. SEND_P3_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
  186. SEND_P3_DATA(StatisticMode, __PERMEDIA_DISABLE);
  187. SEND_P3_DATA(FilterMode, __PERMEDIA_DISABLE);
  188. P3_ENSURE_DX_SPACE(30);
  189. WAIT_FIFO(30);
  190. // Frame buffer
  191. SEND_P3_DATA(FBSourceData, __PERMEDIA_DISABLE);
  192. SEND_P3_DATA(FBHardwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
  193. SEND_P3_DATA(FBSoftwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
  194. SEND_P3_DATA(FBWriteMode, __PERMEDIA_ENABLE);
  195. // We sometimes use the scissor in DDRAW to scissor out unnecessary pixels.
  196. SEND_P3_DATA(ScissorMinXY, 0);
  197. SEND_P3_DATA(ScissorMaxXY, (pThisDisplay->cyMemory << 16) |
  198. (pThisDisplay->cxMemory) );
  199. SEND_P3_DATA(ScreenSize, (pThisDisplay->cyMemory << 16) |
  200. (pThisDisplay->cxMemory) );
  201. SEND_P3_DATA(WindowOrigin, 0x0);
  202. // DirectDraw might not need to set these up
  203. SEND_P3_DATA(dXDom, 0x0);
  204. SEND_P3_DATA(dXSub, 0x0);
  205. SEND_P3_DATA(dY, 1 << 16);
  206. P3_ENSURE_DX_SPACE(32);
  207. WAIT_FIFO(32);
  208. SEND_P3_DATA(GIDMode, __PERMEDIA_DISABLE);
  209. SEND_P3_DATA(YUVMode, __PERMEDIA_DISABLE);
  210. // Delta Unit
  211. SEND_P3_DATA(DeltaControl, 0);
  212. SEND_P3_DATA(DeltaMode, __PERMEDIA_DISABLE);
  213. SEND_P3_DATA(FBSourceReadMode, __PERMEDIA_DISABLE);
  214. SEND_P3_DATA(FBDestReadMode, __PERMEDIA_DISABLE);
  215. SEND_P3_DATA(FBDestReadEnables, __PERMEDIA_DISABLE);
  216. // DDraw driver code doesn't want offsets
  217. SEND_P3_DATA(LBSourceReadBufferOffset, 0);
  218. SEND_P3_DATA(LBDestReadBufferOffset, 0);
  219. SEND_P3_DATA(LBWriteBufferOffset, 0);
  220. SEND_P3_DATA(FBWriteBufferOffset0, 0);
  221. SEND_P3_DATA(FBDestReadBufferOffset0, 0);
  222. SEND_P3_DATA(FBSourceReadBufferOffset, 0);
  223. P3_ENSURE_DX_SPACE(12);
  224. WAIT_FIFO(12);
  225. // Local buffer
  226. SEND_P3_DATA(LBSourceReadMode, __PERMEDIA_DISABLE);
  227. SEND_P3_DATA(LBDestReadMode, __PERMEDIA_DISABLE);
  228. SEND_P3_DATA(LBWriteMode, __PERMEDIA_DISABLE);
  229. SEND_P3_DATA(LBWriteFormat, __PERMEDIA_DISABLE);
  230. // Blending
  231. SEND_P3_DATA(AlphaBlendAlphaMode, __PERMEDIA_DISABLE);
  232. SEND_P3_DATA(AlphaBlendColorMode, __PERMEDIA_DISABLE);
  233. P3_ENSURE_DX_SPACE(32);
  234. WAIT_FIFO(32);
  235. // Texturing (disable)
  236. SEND_P3_DATA(TextureReadMode0, __PERMEDIA_DISABLE);
  237. SEND_P3_DATA(TextureReadMode1, __PERMEDIA_DISABLE);
  238. SEND_P3_DATA(TextureIndexMode0, __PERMEDIA_DISABLE);
  239. SEND_P3_DATA(TextureIndexMode1, __PERMEDIA_DISABLE);
  240. SEND_P3_DATA(TextureCompositeMode, __PERMEDIA_DISABLE);
  241. SEND_P3_DATA(TextureCoordMode, __PERMEDIA_DISABLE);
  242. SEND_P3_DATA(TextureApplicationMode, __PERMEDIA_DISABLE);
  243. SEND_P3_DATA(ChromaTestMode, __PERMEDIA_DISABLE);
  244. SEND_P3_DATA(TextureFilterMode, __PERMEDIA_DISABLE);
  245. SEND_P3_DATA(LUTTransfer, __PERMEDIA_DISABLE);
  246. SEND_P3_DATA(LUTIndex, __PERMEDIA_DISABLE);
  247. SEND_P3_DATA(LUTAddress, __PERMEDIA_DISABLE);
  248. SEND_P3_DATA(LUTMode, __PERMEDIA_DISABLE);
  249. SEND_P3_DATA(RasterizerMode, __PERMEDIA_DISABLE);
  250. // Router setup. DDRAW doesn't care about Z Writes
  251. SEND_P3_DATA(RouterMode, __PERMEDIA_ENABLE);
  252. P3_DMA_COMMIT_BUFFER();
  253. } //HWC_SwitchToDDRAW
  254. //-----------------------------------------------------------------------------
  255. //
  256. // HWC_SwitchToD3D
  257. //
  258. // Writes any hardware registers that need updating on entry into the
  259. // DirectX driver, which are appropriate specifically to Direct3D
  260. //
  261. //-----------------------------------------------------------------------------
  262. void
  263. HWC_SwitchToD3D(
  264. P3_D3DCONTEXT *pContext,
  265. P3_THUNKEDDATA* pThisDisplay,
  266. BOOL bDXEntry)
  267. {
  268. P3_SOFTWARECOPY* pSoftPermedia = &pContext->SoftCopyGlint;
  269. int i;
  270. P3_DMA_DEFS();
  271. // Switch first to the common DX/DDraw/D3D setup
  272. __HWC_SwitchToDX(pThisDisplay, bDXEntry);
  273. P3_DMA_GET_BUFFER();
  274. #if DBG
  275. ASSERTDD(IS_DXCONTEXT_CURRENT(pThisDisplay),
  276. "ERROR: DX Context not current in HWC_SwitchToDDRAW!");
  277. if ( ((ULONG_PTR)dmaPtr >= (ULONG_PTR)pThisDisplay->pGlint->GPFifo) &&
  278. ((ULONG_PTR)dmaPtr <= (ULONG_PTR)pThisDisplay->pGlint->GPFifo + 4000) )
  279. {
  280. ASSERTDD(pThisDisplay->pGLInfo->InterfaceType != GLINT_DMA,
  281. "Error: In FIFO space and setup for DMA");
  282. }
  283. else
  284. {
  285. ASSERTDD(pThisDisplay->pGLInfo->InterfaceType == GLINT_DMA,
  286. "Error: In DMA space and setup for FIFO's");
  287. }
  288. #endif
  289. // Now we restore default values and restore D3D context dependent settings
  290. // directly from what we stored in our context structure.
  291. // Common registers
  292. P3_ENSURE_DX_SPACE(32);
  293. WAIT_FIFO(16);
  294. SEND_P3_DATA(WindowOrigin, 0);
  295. SEND_P3_DATA(AreaStippleMode, 1);
  296. COPY_P3_DATA(DitherMode, pSoftPermedia->DitherMode);
  297. WAIT_FIFO(16);
  298. COPY_P3_DATA(ColorDDAMode, pSoftPermedia->ColorDDAMode);
  299. COPY_P3_DATA(Window, pSoftPermedia->PermediaWindow);
  300. #if DX8_DDI
  301. SEND_P3_DATA(FBHardwareWriteMask, pContext->dwColorWriteHWMask);
  302. SEND_P3_DATA(FBSoftwareWriteMask, pContext->dwColorWriteSWMask);
  303. #else
  304. SEND_P3_DATA(FBHardwareWriteMask,
  305. pContext->RenderStates[D3DRENDERSTATE_PLANEMASK]);
  306. SEND_P3_DATA(FBSoftwareWriteMask, __GLINT_ALL_WRITEMASKS_SET);
  307. #endif
  308. SEND_P3_DATA(FilterMode, __PERMEDIA_DISABLE);
  309. // Force the flat stippled alpha renderers to reload
  310. // the stipple pattern if needed.
  311. P3_ENSURE_DX_SPACE(32); // First 16 Stipple registers
  312. WAIT_FIFO(32);
  313. for( i = 0; i < 16; i++ )
  314. {
  315. SEND_P3_DATA_OFFSET( AreaStipplePattern0,
  316. (DWORD)pContext->CurrentStipple[i], i );
  317. }
  318. P3_ENSURE_DX_SPACE(32); // Second set of 16 Stipple registers
  319. WAIT_FIFO(32); // (loaded separately to have GVX1 compatibilty)
  320. for( i = 16; i < 32; i++ )
  321. {
  322. SEND_P3_DATA_OFFSET( AreaStipplePattern0,
  323. (DWORD)pContext->CurrentStipple[i], i );
  324. }
  325. P3_ENSURE_DX_SPACE(32);
  326. WAIT_FIFO(32);
  327. SEND_P3_DATA(GIDMode, 0);
  328. // Don't want offsets
  329. SEND_P3_DATA(LBSourceReadBufferOffset, 0);
  330. SEND_P3_DATA(LBDestReadBufferOffset, 0);
  331. SEND_P3_DATA(LBWriteBufferOffset, 0);
  332. SEND_P3_DATA(FBWriteBufferOffset0, 0);
  333. SEND_P3_DATA(FBDestReadBufferOffset0, 0);
  334. SEND_P3_DATA(FBSourceReadBufferOffset, 0);
  335. // Frame buffer
  336. SEND_P3_DATA(FBSourceReadMode, __PERMEDIA_DISABLE);
  337. SEND_P3_DATA(FBDestReadMode, __PERMEDIA_DISABLE);
  338. SEND_P3_DATA(FBDestReadEnables, __PERMEDIA_DISABLE);
  339. SEND_P3_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
  340. SEND_P3_DATA(GIDMode, __PERMEDIA_DISABLE);
  341. SEND_P3_DATA(YUVMode, __PERMEDIA_DISABLE);
  342. // Frame buffer
  343. COPY_P3_DATA(FBWriteMode, pSoftPermedia->P3RXFBWriteMode);
  344. // Delta
  345. COPY_P3_DATA(DeltaMode, pSoftPermedia->P3RX_P3DeltaMode);
  346. COPY_P3_DATA(DeltaControl, pSoftPermedia->P3RX_P3DeltaControl);
  347. P3_ENSURE_DX_SPACE(32);
  348. WAIT_FIFO(32);
  349. SEND_P3_DATA(XBias, *(DWORD*)&pContext->XBias);
  350. SEND_P3_DATA(YBias, *(DWORD*)&pContext->YBias);
  351. // Disable chroma tests
  352. SEND_P3_DATA(ChromaTestMode, __PERMEDIA_DISABLE);
  353. // Router setup
  354. SEND_P3_DATA(RouterMode, __PERMEDIA_ENABLE);
  355. SEND_P3_DATA( VertexTagList0, V0FloatX_Tag );
  356. SEND_P3_DATA( VertexTagList1, V0FloatY_Tag );
  357. SEND_P3_DATA( VertexTagList2, V0FloatZ_Tag );
  358. SEND_P3_DATA( VertexTagList3, V0FloatQ_Tag );
  359. SEND_P3_DATA( VertexTagList4, V0FloatPackedColour_Tag );
  360. SEND_P3_DATA( VertexTagList5, V0FloatPackedSpecularFog_Tag );
  361. SEND_P3_DATA( VertexTagList6, V0FloatS_Tag );
  362. SEND_P3_DATA( VertexTagList7, V0FloatT_Tag );
  363. SEND_P3_DATA( VertexTagList8, V0FloatS1_Tag );
  364. SEND_P3_DATA( VertexTagList9, V0FloatT1_Tag );
  365. // Restore the texturecachereplacement mode.
  366. COPY_P3_DATA(TextureCacheReplacementMode,
  367. pSoftPermedia->P3RXTextureCacheReplacementMode);
  368. SEND_P3_DATA( ProvokingVertexMask, 0xfff );
  369. P3_ENSURE_DX_SPACE(8);
  370. WAIT_FIFO(8);
  371. COPY_P3_DATA( LineStippleMode, pSoftPermedia->PXRXLineStippleMode);
  372. P3_DMA_COMMIT_BUFFER();
  373. //@@BEGIN_DDKSPLIT
  374. // azn - is this really necessary???
  375. //@@END_DDKSPLIT
  376. // This will cause the FVF state to be recalculated
  377. ZeroMemory(&pContext->FVFData, sizeof(FVFOFFSETS));
  378. // Force everything to be set up again before rendering
  379. DIRTY_EVERYTHING(pContext);
  380. } // HWC_SwitchToD3D
  381. //-----------------------------------------------------------------------------
  382. //
  383. // HWC_SwitchToFIFO
  384. //
  385. // Allows us to switch from DMA mode to FIFO transfers
  386. //
  387. //-----------------------------------------------------------------------------
  388. void HWC_SwitchToFIFO( P3_THUNKEDDATA* pThisDisplay, LPGLINTINFO pGLInfo )
  389. {
  390. P3_DMA_DEFS();
  391. if (pGLInfo->InterfaceType != GLINT_NON_DMA)
  392. {
  393. DISPDBG((WRNLVL,"Switching to 4K Funny FIFO Memory"));
  394. P3_DMA_GET_BUFFER();
  395. P3_DMA_FLUSH_BUFFER();
  396. SYNC_WITH_GLINT;
  397. pGLInfo->InterfaceType = GLINT_NON_DMA;
  398. pGLInfo->CurrentBuffer = (ULONG *)pThisDisplay->pGlint->GPFifo;
  399. }
  400. else
  401. {
  402. // This means we already are in FIFO mode
  403. DISPDBG((DBGLVL,"NOT Switching to 4K Funny FIFO Memory"));
  404. }
  405. } // HWC_SwitchToFIFO
  406. //-----------------------------------------------------------------------------
  407. //
  408. // HWC_SwitchToDMA
  409. //
  410. // Allows us to switch from FIFO transfers to DMA mode
  411. //
  412. //-----------------------------------------------------------------------------
  413. void HWC_SwitchToDMA( P3_THUNKEDDATA* pThisDisplay, LPGLINTINFO pGLInfo )
  414. {
  415. if (pGLInfo->InterfaceType != GLINT_DMA)
  416. {
  417. DISPDBG((WRNLVL,"Switching to DMA buffers"));
  418. SYNC_WITH_GLINT;
  419. pGLInfo->InterfaceType = GLINT_DMA;
  420. pGLInfo->CurrentBuffer =
  421. pGLInfo->DMAPartition[pGLInfo->CurrentPartition].VirtAddr;
  422. }
  423. else
  424. {
  425. DISPDBG((WRNLVL,"NOT Switching to DMA buffers"));
  426. }
  427. } // HWC_SwitchToDMA
  428. //-----------------------------------------------------------------------------
  429. //
  430. // __HWC_RecalculateDXDMABuffers
  431. //
  432. // Run through the OpanGL buffer mask to determine which remaining piece of
  433. // buffer is the biggest and setup DirectX to use this buffer.
  434. //
  435. //-----------------------------------------------------------------------------
  436. void
  437. __HWC_RecalculateDXDMABuffers(
  438. P3_THUNKEDDATA* pThisDisplay)
  439. {
  440. DWORD dwSize, i;
  441. LPGLINTINFO pGLInfo = pThisDisplay->pGLInfo;
  442. if (pGLInfo->InterfaceType != GLINT_DMA)
  443. {
  444. // exit if we are not using DMA
  445. return;
  446. }
  447. // Just use the entire DMA Buffer.
  448. pThisDisplay->DMAInfo.dwBuffSize =
  449. pThisDisplay->pGLInfo->dw3DDMABufferSize;
  450. pThisDisplay->DMAInfo.dwBuffPhys =
  451. pThisDisplay->pGLInfo->dw3DDMABufferPhys;
  452. pThisDisplay->DMAInfo.dwBuffVirt =
  453. pThisDisplay->pGLInfo->dw3DDMABufferVirt;
  454. DISPDBG((DBGLVL,"__HWC_RecalculateDXDMABuffers V:0x%p P:0x%x S:0x%x",
  455. pThisDisplay->DMAInfo.dwBuffVirt,
  456. pThisDisplay->DMAInfo.dwBuffPhys,
  457. pThisDisplay->DMAInfo.dwBuffSize));
  458. dwSize = ((DWORD)(pThisDisplay->DMAInfo.dwBuffSize) /
  459. (DWORD)pGLInfo->NumberOfSubBuffers);
  460. dwSize = ((dwSize + 3) & ~3);
  461. pThisDisplay->PartitionSize = dwSize / sizeof(DWORD);
  462. DISPDBG((DBGLVL,"Got Buffer with 0x%x Sub Buffers",
  463. pGLInfo->NumberOfSubBuffers));
  464. for (i = 0; i < pGLInfo->NumberOfSubBuffers; i++)
  465. {
  466. pGLInfo->DMAPartition[i].VirtAddr =
  467. (ULONG *)((char*)(pThisDisplay->DMAInfo.dwBuffVirt) +
  468. (i * dwSize));
  469. pGLInfo->DMAPartition[i].PhysAddr =
  470. (DWORD)((pThisDisplay->DMAInfo.dwBuffPhys) +
  471. (i * dwSize));
  472. pGLInfo->DMAPartition[i].MaxAddress =
  473. (ULONG_PTR)pGLInfo->DMAPartition[i].VirtAddr + dwSize;
  474. pGLInfo->DMAPartition[i].Locked = FALSE;
  475. DISPDBG((DBGLVL," Partition%d: VirtAddr = 0x%x, "
  476. " PhysAddr = 0x%x, MaxAddres = 0x%x",
  477. i,
  478. pGLInfo->DMAPartition[i].VirtAddr,
  479. pGLInfo->DMAPartition[i].PhysAddr,
  480. pGLInfo->DMAPartition[i].MaxAddress));
  481. #if DBG
  482. pGLInfo->DMAPartition[i].bStampedDMA = TRUE;
  483. //@@BEGIN_DDKSPLIT
  484. #if 0
  485. //azn hard to say in 64 bits!
  486. memset((void*)pGLInfo->DMAPartition[i].VirtAddr,
  487. 0x4D,
  488. (pGLInfo->DMAPartition[i].MaxAddress -
  489. pGLInfo->DMAPartition[i].VirtAddr));
  490. #endif
  491. //@@END_DDKSPLIT
  492. #endif
  493. }
  494. pGLInfo->CurrentBuffer =
  495. pGLInfo->DMAPartition[pGLInfo->CurrentPartition].VirtAddr;
  496. } // __HWC_RecalculateDXDMABuffers
  497. //-----------------------------------------------------------------------------
  498. //
  499. // HWC_StartDMA
  500. //
  501. //-----------------------------------------------------------------------------
  502. DWORD WINAPI
  503. HWC_StartDMA(
  504. P3_THUNKEDDATA* pThisDisplay,
  505. DWORD dwContext,
  506. DWORD dwSize,
  507. DWORD dwPhys,
  508. ULONG_PTR dwVirt,
  509. DWORD dwEvent)
  510. {
  511. LPGLINTINFO pGLInfo = pThisDisplay->pGLInfo;
  512. ASSERTDD( (int)dwSize > 0, "DMA buffer size non-positive" );
  513. ASSERTDD((IS_DXCONTEXT_CURRENT(pThisDisplay) &&
  514. (pGLInfo->InterfaceType == GLINT_DMA)),
  515. "Error, Trying DMA when not setup for it!" );
  516. #if W95_DDRAW
  517. ASSERTDD( pGLInfo->endIndex != 0, "Trying DMA with zero sub-buffers" );
  518. #endif
  519. #if DBG
  520. pGLInfo->DMAPartition[pGLInfo->CurrentPartition].bStampedDMA = FALSE;
  521. #endif
  522. #ifdef W95_DDRAW
  523. ASSERTDD(pThisDisplay->pGLInfo->dwCurrentContext != CONTEXT_DISPLAY_HANDLE,
  524. "HWC_StartDMA: In display driver context" )
  525. ASSERTDD( pThisDisplay->pGlint->FilterMode == 0,
  526. "FilterMode non-zero" );
  527. #endif
  528. #if WNT_DDRAW
  529. DDSendDMAData(pThisDisplay->ppdev, dwPhys, dwVirt, dwSize);
  530. #else
  531. StartDMAProper(pThisDisplay, pGLInfo, dwPhys, dwVirt, dwSize);
  532. #endif
  533. DISPDBG((DBGLVL, "HWC_StartDMA sent %d dwords", dwSize));
  534. return GLDD_SUCCESS;
  535. } // HWC_StartDMA
  536. //-----------------------------------------------------------------------------
  537. //
  538. // HWC_AllocDMABuffer
  539. //
  540. //-----------------------------------------------------------------------------
  541. void
  542. HWC_AllocDMABuffer(
  543. P3_THUNKEDDATA* pThisDisplay)
  544. {
  545. LPGLINTINFO pGLInfo = pThisDisplay->pGLInfo;
  546. int i;
  547. DWORD bDMA = TRUE;
  548. BOOL bRet;
  549. DWORD Result;
  550. // Empty the DMA partition slots
  551. for (i = 0; i < MAX_SUBBUFFERS; i++)
  552. {
  553. pGLInfo->DMAPartition[i].PhysAddr = 0;
  554. pGLInfo->DMAPartition[i].VirtAddr = 0;
  555. pGLInfo->DMAPartition[i].MaxAddress = 0;
  556. }
  557. #if WNT_DDRAW
  558. // DMA turned off
  559. bDMA = FALSE;
  560. #else
  561. // Are we allowed to DMA?
  562. bRet = GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.NoDMA", &Result);
  563. if ((bRet && (Result != 0)) ||
  564. (pThisDisplay->pGLInfo->dw3DDMABufferSize == 0))
  565. {
  566. bDMA = FALSE;
  567. }
  568. #endif
  569. // Find out how many sub buffers the user wants.
  570. bRet = GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.SubBuffers", &Result);
  571. if ((Result == 0) || (bRet == FALSE))
  572. {
  573. // Default
  574. pGLInfo->NumberOfSubBuffers = DEFAULT_SUBBUFFERS;
  575. }
  576. else
  577. {
  578. if (Result > MAX_SUBBUFFERS)
  579. {
  580. pGLInfo->NumberOfSubBuffers = MAX_SUBBUFFERS;
  581. }
  582. else
  583. {
  584. pGLInfo->NumberOfSubBuffers = Result;
  585. }
  586. if (pGLInfo->NumberOfSubBuffers < 2)
  587. {
  588. pGLInfo->NumberOfSubBuffers = 2;
  589. }
  590. }
  591. // if no interrupt driven DMA or asked for less than 3 buffers then
  592. // configure no Q for this context
  593. if ((pGLInfo->dwFlags & GMVF_NOIRQ) || (pGLInfo->NumberOfSubBuffers < 2))
  594. {
  595. pGLInfo->NumberOfSubBuffers = 2;
  596. }
  597. DISPDBG((DBGLVL,"Setting 0x%x Sub Buffers", pGLInfo->NumberOfSubBuffers));
  598. // Initialise for no DMA if DMA has been turned off for whatever reason
  599. if (!bDMA)
  600. {
  601. DISPDBG((WRNLVL,"Using 4K Funny FIFO Memory"));
  602. pGLInfo->InterfaceType = GLINT_NON_DMA;
  603. pThisDisplay->StartDMA = 0;
  604. pGLInfo->NumberOfSubBuffers = 0;
  605. pGLInfo->CurrentBuffer = (ULONG *)pThisDisplay->pGlint->GPFifo;
  606. pThisDisplay->b2D_FIFOS = TRUE;
  607. }
  608. else
  609. {
  610. // DMA Setup
  611. pGLInfo->InterfaceType = GLINT_DMA;
  612. pThisDisplay->StartDMA = HWC_StartDMA;
  613. // This call will actually setup the partitions
  614. __HWC_RecalculateDXDMABuffers(pThisDisplay);
  615. // Is DirectDraw DMA disabled?
  616. bRet = GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.No2DDMA", &Result);
  617. if (bRet && (Result == 1))
  618. {
  619. pThisDisplay->b2D_FIFOS = TRUE;
  620. }
  621. else
  622. {
  623. pThisDisplay->b2D_FIFOS = FALSE;
  624. }
  625. }
  626. #if W95_DDRAW
  627. // Store the end index in the context.
  628. SetEndIndex(pGLInfo,
  629. CONTEXT_DIRECTX_HANDLE,
  630. (unsigned short)pGLInfo->NumberOfSubBuffers);
  631. #endif // W95_DDRAW
  632. if (pGLInfo->InterfaceType == GLINT_NON_DMA)
  633. {
  634. DISPDBG((WRNLVL,"DDRAW: Using FIFO's"));
  635. }
  636. else
  637. {
  638. DISPDBG((WRNLVL,"DDRAW: Using DMA"));
  639. }
  640. } // HWC_AllocDMABuffer
  641. //-----------------------------------------------------------------------------
  642. //
  643. // HWC_FlushDXBuffer
  644. //
  645. //-----------------------------------------------------------------------------
  646. void
  647. HWC_FlushDXBuffer(
  648. P3_THUNKEDDATA* pThisDisplay )
  649. {
  650. LPGLINTINFO pGLInfo = pThisDisplay->pGLInfo;
  651. if( pGLInfo->InterfaceType == GLINT_DMA )
  652. {
  653. DWORD Send;
  654. P3_DMAPartition *pCurrDMAPartition;
  655. pCurrDMAPartition = &(pGLInfo->DMAPartition[pGLInfo->CurrentPartition]);
  656. //@@BEGIN_DDKSPLIT
  657. // azn - we might lose 64 bit precision here!
  658. //@@END_DDKSPLIT
  659. Send = (DWORD)(pGLInfo->CurrentBuffer - pCurrDMAPartition->VirtAddr)
  660. / sizeof(DWORD);
  661. if( Send )
  662. {
  663. ASSERTDD( Send < 0x10000, "Wacky DMA size" );
  664. ((__StartDMA)pThisDisplay->StartDMA)
  665. (pThisDisplay,
  666. CONTEXT_DIRECTX_HANDLE,
  667. Send,
  668. (DWORD)(pCurrDMAPartition->PhysAddr),
  669. (ULONG_PTR)(pCurrDMAPartition->VirtAddr),
  670. 0);
  671. pGLInfo->CurrentPartition++;
  672. if (pGLInfo->CurrentPartition == pGLInfo->NumberOfSubBuffers)
  673. {
  674. pGLInfo->CurrentPartition = 0;
  675. }
  676. ASSERTDD(!pGLInfo->DMAPartition[pGLInfo->CurrentPartition].Locked,
  677. "Partition already locked" );
  678. }
  679. pGLInfo->CurrentBuffer =
  680. pGLInfo->DMAPartition[pGLInfo->CurrentPartition].VirtAddr;
  681. }
  682. else
  683. {
  684. pGLInfo->CurrentBuffer = (ULONG *)pThisDisplay->pGlint->GPFifo;
  685. }
  686. } // HWC_FlushDXBuffer
  687. #if DBG
  688. //-----------------------------------------------------------------------------
  689. //
  690. // HWC_GetDXBuffer
  691. //
  692. //-----------------------------------------------------------------------------
  693. void
  694. HWC_GetDXBuffer(
  695. P3_THUNKEDDATA* pThisDisplay,
  696. char *file,
  697. int line )
  698. {
  699. LPGLINTINFO pGLInfo = pThisDisplay->pGLInfo;
  700. ASSERTDD( pGLInfo->dwFlags & GMVF_GCOP, "VDD not locked out" );
  701. ASSERTDD( !pThisDisplay->BufferLocked, "Buffer already locked" );
  702. pThisDisplay->BufferLocked = TRUE;
  703. #ifdef WANT_DMA
  704. if(( pGLInfo->endIndex > 2 ) && !IS_DXCONTEXT_CURRENT(pThisDisplay))
  705. {
  706. ASSERTDD( pGLInfo->CurrentBuffer ==
  707. pGLInfo->DMAPartition[pGLInfo->CurrentPartition].VirtAddr,
  708. "Trying to DMA in display driver context" );
  709. }
  710. #endif
  711. DISPDBG(( DBGLVL, "HWC_GetDXBuffer: %s %d: Curr part %d, dmaPtr 0x%08x",
  712. file, line,
  713. pGLInfo->CurrentPartition, pGLInfo->CurrentBuffer ));
  714. if (pGLInfo->InterfaceType == GLINT_DMA)
  715. {
  716. DISPDBG(( DBGLVL, "HWC_GetDXBuffer: %d dwords to flush",
  717. ( pGLInfo->CurrentBuffer -
  718. pGLInfo->DMAPartition[pGLInfo->CurrentPartition].VirtAddr ) / 4 ));
  719. }
  720. else
  721. {
  722. DISPDBG(( DBGLVL, "HWC_GetDXBuffer: Using FIFOs"));
  723. }
  724. #ifdef WANT_DMA
  725. // Ensure nobody has scribbled on the DMA Buffer
  726. if(( pGLInfo->InterfaceType == GLINT_DMA ) &&
  727. (pGLInfo->DMAPartition[pGLInfo->CurrentPartition].bStampedDMA) )
  728. {
  729. ASSERTDD( *(DWORD*)pThisDisplay->pGLInfo->CurrentBuffer == 0x4D4D4D4D,
  730. "ERROR: DMA Buffer signature invalid!" );
  731. }
  732. // Ensure we aren't writing to the wrong region
  733. if(IS_DXCONTEXT_CURRENT(pThisDisplay) &&
  734. ( pThisDisplay->pGLInfo->InterfaceType != GLINT_UNKNOWN_INTERFACE ))
  735. {
  736. if ((((ULONG_PTR)pThisDisplay->pGLInfo->CurrentBuffer >=
  737. (ULONG_PTR)pThisDisplay->pGlint->GPFifo)) &&
  738. ((ULONG_PTR)pThisDisplay->pGLInfo->CurrentBuffer <=
  739. ((ULONG_PTR)pThisDisplay->pGlint->GPFifo + 4000)) )
  740. {
  741. ASSERTDD(pThisDisplay->pGLInfo->InterfaceType == GLINT_NON_DMA,
  742. "Error: In FIFO space and setup for DMA");
  743. }
  744. else
  745. {
  746. ASSERTDD(pThisDisplay->pGLInfo->InterfaceType == GLINT_DMA,
  747. "Error: In DMA space and setup for FIFO's");
  748. }
  749. }
  750. #endif
  751. } // HWC_GetDXBuffer
  752. //-----------------------------------------------------------------------------
  753. //
  754. // HWC_SetDXBuffer
  755. //
  756. //-----------------------------------------------------------------------------
  757. void
  758. HWC_SetDXBuffer(
  759. P3_THUNKEDDATA* pThisDisplay,
  760. char *file,
  761. int line )
  762. {
  763. LPGLINTINFO pGLInfo = pThisDisplay->pGLInfo;
  764. ASSERTDD( pGLInfo->dwFlags & GMVF_GCOP, "VDD not locked out" );
  765. pThisDisplay->BufferLocked = FALSE;
  766. DISPDBG(( DBGLVL, "HWC_SetDXBuffer: %s %d: Curr part %d, dmaPtr 0x%08x",
  767. file, line,
  768. pGLInfo->CurrentPartition, pGLInfo->CurrentBuffer ));
  769. if (pGLInfo->InterfaceType == GLINT_DMA)
  770. {
  771. DISPDBG(( DBGLVL, "HWC_SetDXBuffer: %d dwords to flush",
  772. ( pGLInfo->CurrentBuffer -
  773. pGLInfo->DMAPartition[pGLInfo->CurrentPartition].VirtAddr ) / 4 ));
  774. }
  775. else
  776. {
  777. DISPDBG(( DBGLVL, "HWC_SetDXBuffer: Using FIFOs"));
  778. }
  779. #ifdef WANT_DMA
  780. // Ensure nobody has scribbled on the DMA Buffer
  781. if(( pGLInfo->InterfaceType == GLINT_DMA ) &&
  782. (pGLInfo->DMAPartition[pGLInfo->CurrentPartition].bStampedDMA) )
  783. {
  784. ASSERTDD( *(DWORD*)pThisDisplay->pGLInfo->CurrentBuffer == 0x4D4D4D4D,
  785. "ERROR: DMA Buffer signature invalid!" );
  786. }
  787. // Ensure we aren't writing to the wrong region
  788. if(IS_DXCONTEXT_CURRENT(pThisDisplay) &&
  789. ( pThisDisplay->pGLInfo->InterfaceType != GLINT_UNKNOWN_INTERFACE ))
  790. {
  791. if ((((ULONG_PTR)pThisDisplay->pGLInfo->CurrentBuffer >=
  792. (ULONG_PTR)pThisDisplay->pGlint->GPFifo)) &&
  793. ((ULONG_PTR)pThisDisplay->pGLInfo->CurrentBuffer <=
  794. ((ULONG_PTR)pThisDisplay->pGlint->GPFifo + 4000)) )
  795. {
  796. ASSERTDD(pThisDisplay->pGLInfo->InterfaceType == GLINT_NON_DMA,
  797. "Error: In FIFO space and setup for DMA");
  798. }
  799. else
  800. {
  801. ASSERTDD(pThisDisplay->pGLInfo->InterfaceType == GLINT_DMA,
  802. "Error: In DMA space and setup for FIFO's");
  803. }
  804. }
  805. #endif // WANT_DMA
  806. } // HWC_SetDXBuffer
  807. //-----------------------------------------------------------------------------
  808. //
  809. // HWC_bRenderIDHasCompleted
  810. //
  811. // This is simply the paranoid version of the macro
  812. // declared in directx.h. It is present only in checked (debug)
  813. // builds, since the non-debug version is just a
  814. // one-line #define.
  815. //-----------------------------------------------------------------------------
  816. BOOL
  817. HWC_bRenderIDHasCompleted (
  818. DWORD dwID,
  819. P3_THUNKEDDATA* pThisDisplay )
  820. {
  821. DWORD dwCurID, dwCurHostID;
  822. int iTemp;
  823. ASSERTDD (CHIP_RENDER_ID_IS_VALID(),
  824. "** RENDER_ID_HAS_COMPLETED: Chip's RenderID is not valid." );
  825. dwCurID = GET_CURRENT_CHIP_RENDER_ID();
  826. // Make sure the invalid bits have been zapped.
  827. ASSERTDD ( ( dwCurID | RENDER_ID_KNACKERED_BITS ) == dwCurID,
  828. "** RENDER_ID_HAS_COMPLETED: Current chip ID is invalid" );
  829. ASSERTDD ( ( dwID | RENDER_ID_KNACKERED_BITS ) == dwID,
  830. "** RENDER_ID_HAS_COMPLETED: Checked ID is invalid" );
  831. // We need to cope with the fact that the MinRegion register sign-extends
  832. // some bits in the middle, irritatingly. It's not a problem for simple
  833. // >=< tests, but this wants to know _how much_ we are out.
  834. // Bits 0xf000f000 are rubbish, so we need to chop them out.
  835. // This is not a problem on P3, and the RENDER_ID_VALID macros are set up
  836. // so this code will basically be compiled out of existence.
  837. dwCurID = ( dwCurID & RENDER_ID_VALID_BITS_LOWER ) |
  838. ( ( dwCurID & RENDER_ID_VALID_BITS_UPPER ) >>
  839. RENDER_ID_VALID_BITS_UPPER_SHIFT );
  840. dwID = ( dwID & RENDER_ID_VALID_BITS_LOWER ) |
  841. ( ( dwID & RENDER_ID_VALID_BITS_UPPER ) >>
  842. RENDER_ID_VALID_BITS_UPPER_SHIFT );
  843. iTemp = (signed)( dwCurID - dwID );
  844. // Cope with the dodgy sign bits - sign extend the top n bits.
  845. iTemp <<= RENDER_ID_VALID_BITS_SIGN_SHIFT;
  846. iTemp >>= RENDER_ID_VALID_BITS_SIGN_SHIFT;
  847. // Some fairly arbitrary boundaries. If they are too small
  848. // for common use, just enlarge them a bit.
  849. // Generally, dwCurId can be well ahead of my_id (if the surface
  850. // hasn't been used for ages), but should not be too far behind,
  851. // because the pipe isn't _that_ big.
  852. if ( ( iTemp < RENDER_ID_LOWER_LIMIT ) ||
  853. ( iTemp > RENDER_ID_UPPER_LIMIT ) )
  854. {
  855. DISPDBG (( ERRLVL," ** Current chip ID 0x%x, surface ID, 0x%x",
  856. dwCurID, dwID ));
  857. DISPDBG ((ERRLVL,"** RENDER_ID_HAS_COMPLETED: Current render"
  858. " ID is a long way out from surface's." ));
  859. }
  860. // We should never have a render ID newer
  861. // than the current host render ID.
  862. dwCurHostID = GET_HOST_RENDER_ID();
  863. // Make sure the invalid bits have been zapped.
  864. ASSERTDD ( ( dwCurHostID | RENDER_ID_KNACKERED_BITS ) == dwCurHostID,
  865. "** RENDER_ID_HAS_COMPLETED: Current host ID is invalid" );
  866. // Get a real contiguous number.
  867. dwCurHostID = ( dwCurHostID & RENDER_ID_VALID_BITS_LOWER ) |
  868. ( ( dwCurHostID & RENDER_ID_VALID_BITS_UPPER ) >>
  869. RENDER_ID_VALID_BITS_UPPER_SHIFT );
  870. iTemp = (signed)( dwCurHostID - dwID );
  871. // Cope with the dodgy sign bits - sign extend the top n bits.
  872. iTemp <<= RENDER_ID_VALID_BITS_SIGN_SHIFT;
  873. iTemp >>= RENDER_ID_VALID_BITS_SIGN_SHIFT;
  874. if ( iTemp < 0 )
  875. {
  876. DISPDBG ((ERRLVL," ** Current host ID 0x%x, surface ID, 0x%x",
  877. dwCurHostID, dwID ));
  878. // This may be caused by wrapping, of course.
  879. DISPDBG ((ERRLVL, "** RENDER_ID_HAS_COMPLETED: Surface's ID is "
  880. "more recent than current host render ID." ));
  881. }
  882. return ( !RENDER_ID_LESS_THAN ( dwCurID, dwID ) );
  883. } // HWC_bRenderIDHasCompleted
  884. #endif //DBG