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.

856 lines
29 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * **************************
  4. * * DirectDraw SAMPLE CODE *
  5. * **************************
  6. *
  7. * Module Name: ddenable.c
  8. *
  9. * Content: Windows 2000 only DirectDraw/D3D enabling functions
  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 WNT_DDRAW
  16. //-----------------------------------------------------------------------------
  17. //
  18. // ***************************WIN NT ONLY**********************************
  19. //
  20. // __DDE_BuildPixelFormat
  21. //
  22. // generate a pixel format structure based on the mode
  23. // This example works only with RGB surfaces
  24. //
  25. //-----------------------------------------------------------------------------
  26. void
  27. __DDE_BuildPixelFormat(
  28. P3_THUNKEDDATA* pThisDisplay,
  29. LPGLINTINFO pGLInfo,
  30. LPDDPIXELFORMAT pdpf )
  31. {
  32. PPDEV ppdev;
  33. ppdev = pThisDisplay->ppdev;
  34. pdpf->dwSize = sizeof( DDPIXELFORMAT );
  35. pdpf->dwFourCC = 0;
  36. pdpf->dwFlags = DDPF_RGB;
  37. if( pGLInfo->dwBpp == 8 )
  38. {
  39. pdpf->dwFlags |= DDPF_PALETTEINDEXED8;
  40. }
  41. pdpf->dwRGBBitCount = pGLInfo->dwBpp;
  42. pdpf->dwRBitMask = ppdev->flRed;
  43. pdpf->dwGBitMask = ppdev->flGreen;
  44. pdpf->dwBBitMask = ppdev->flBlue;
  45. // Calculate the alpha channel as it isn't in the ppdev
  46. switch (pGLInfo->dwBpp)
  47. {
  48. case 8:
  49. DISPDBG((DBGLVL, "Format is 8 bits"));
  50. pdpf->dwRGBAlphaBitMask = 0;
  51. break;
  52. case 16:
  53. DISPDBG((DBGLVL, "Format is 16 bits"));
  54. switch(ppdev->flRed)
  55. {
  56. case 0x7C00:
  57. pdpf->dwRGBAlphaBitMask = 0x8000L;
  58. pdpf->dwFlags |= DDPF_ALPHAPIXELS;
  59. break;
  60. default:
  61. pdpf->dwRGBAlphaBitMask = 0x0L;
  62. }
  63. break;
  64. case 24:
  65. DISPDBG((DBGLVL, "Format is 24 bits"));
  66. pdpf->dwRGBAlphaBitMask = 0x00000000L;
  67. break;
  68. case 32:
  69. DISPDBG((DBGLVL, "Desktop is 32 bits"));
  70. pdpf->dwRGBAlphaBitMask = 0xff000000L;
  71. pdpf->dwFlags |= DDPF_ALPHAPIXELS;
  72. break;
  73. }
  74. } // __DDE_BuildPixelFormat
  75. //-----------------------------------------------------------------------------
  76. //
  77. // ***************************WIN NT ONLY**********************************
  78. //
  79. // __DDE_bSetupDDStructs
  80. //
  81. // This fills in the data that would have been setup on Win9X in the
  82. // 16 bit side
  83. //
  84. //-----------------------------------------------------------------------------
  85. BOOL
  86. __DDE_bSetupDDStructs(
  87. P3_THUNKEDDATA* pThisDisplay,
  88. BOOL reset )
  89. {
  90. DWORD dwRegistryValue;
  91. BOOL bSuccess;
  92. LPGLINTINFO pGLInfo;
  93. PPDEV ppdev;
  94. void *fbPtr; // Framebuffer pointer
  95. void *lbPtr; // Localbuffer pointer
  96. DWORD fbSizeInBytes; // Size of framebuffer
  97. DWORD lbSizeInBytes; // Size of localbuffer
  98. DWORD fbOffsetInBytes; // Offset to 1st 'free' byte in framebuffer
  99. DWORD dwMemStart, dwMemEnd;
  100. // reset == TRUE if there has been a mode change.
  101. pThisDisplay->bResetMode = reset;
  102. #if DBG
  103. if (pThisDisplay->bResetMode)
  104. {
  105. DISPDBG((DBGLVL,"Resetting due to mode change"));
  106. }
  107. else
  108. {
  109. DISPDBG((DBGLVL, "Creating for the first time"));
  110. }
  111. #endif
  112. // Setup pThisDisplay->pGLInfo from PPDEV
  113. pGLInfo = pThisDisplay->pGLInfo;
  114. ppdev = pThisDisplay->ppdev;
  115. GetFBLBInfoForDDraw (ppdev,
  116. &fbPtr, // Framebuffer pointer
  117. &lbPtr, // Localbuffer pointer,
  118. // (*** This is NULL***)
  119. &fbSizeInBytes, // Size of framebuffer
  120. &lbSizeInBytes, // Size of localbuffer
  121. &fbOffsetInBytes, // Offset to 1st 'free' byte
  122. // in framebuffer
  123. &pGLInfo->bDRAMBoard);// TRUE if SDRAM vidmem,
  124. // FALSE if SGRAM
  125. // (i.e. hw writemask) vidmem
  126. DISPDBG((DBGLVL, "__DDE_bSetupDDStructs: fbPtr 0x%lx, fbOff 0x%x",
  127. fbPtr, fbOffsetInBytes));
  128. // If VBlankStatusPtr is non-NULL then we know that the NT miniport
  129. // will set the VBlankStatusPtr for us.
  130. if (pThisDisplay->VBlankStatusPtr)
  131. pGLInfo->dwFlags = GMVF_VBLANK_ENABLED;// Say that we are using VBLANKs
  132. else
  133. pGLInfo->dwFlags = 0;
  134. pGLInfo->bPixelToBytesShift = (unsigned char)ppdev->cPelSize;
  135. pGLInfo->ddFBSize = fbSizeInBytes;
  136. pGLInfo->dwScreenBase = 0;
  137. pGLInfo->dwOffscreenBase = fbOffsetInBytes;
  138. pGLInfo->dwScreenWidth = ppdev->cxScreen; // Driver info
  139. pGLInfo->dwScreenHeight = ppdev->cyScreen;
  140. pGLInfo->dwVideoWidth = ppdev->cxMemory;
  141. pGLInfo->dwVideoHeight = ppdev->cyMemory;
  142. bSuccess = GET_REGISTRY_ULONG_FROM_STRING(
  143. "HardwareInformation.CurrentPixelClockSpeed",
  144. &dwRegistryValue);
  145. if(!bSuccess)
  146. {
  147. DISPDBG((ERRLVL,"Error - can't determine pixel clock"));
  148. dwRegistryValue = 0;
  149. }
  150. DISPDBG((DBGLVL,"Pixel clock frequency is %dHz", dwRegistryValue));
  151. pGLInfo->PixelClockFrequency = dwRegistryValue;
  152. bSuccess = GET_REGISTRY_ULONG_FROM_STRING(
  153. "HardwareInformation.CurrentMemClockSpeed",
  154. &dwRegistryValue);
  155. if(!bSuccess)
  156. {
  157. DISPDBG((ERRLVL,"Error - can't determine memory clock"));
  158. dwRegistryValue = 0;
  159. }
  160. DISPDBG((DBGLVL,"Memory clock frequency is %dHz", dwRegistryValue));
  161. pGLInfo->MClkFrequency = dwRegistryValue;
  162. if (ppdev->iBitmapFormat == BMF_8BPP)
  163. {
  164. DISPDBG((DBGLVL, "Desktop is 8 bits"));
  165. pGLInfo->dwBpp = 8;
  166. }
  167. else if (ppdev->iBitmapFormat == BMF_16BPP)
  168. {
  169. DISPDBG((DBGLVL, "Desktop is 16 bits"));
  170. pGLInfo->dwBpp = 16;
  171. }
  172. else if (ppdev->iBitmapFormat == BMF_24BPP)
  173. {
  174. DISPDBG((DBGLVL, "Desktop is 24 bits"));
  175. pGLInfo->dwBpp = 24;
  176. }
  177. else
  178. {
  179. DISPDBG((DBGLVL, "Desktop is 32 bits"));
  180. pGLInfo->dwBpp = 32;
  181. }
  182. pGLInfo->dwScreenWidthBytes = ppdev->lDelta;
  183. if (pGLInfo->pRegs == 0)
  184. {
  185. DISPDBG ((WRNLVL, "__DDE_bSetupDDStructs: NULL register set"));
  186. return (FALSE);
  187. }
  188. // Setup the information that is shared with the 32 bit side
  189. // Control points to the RAMDAC
  190. // pGLInfo is a pointer to the DisplayDriver state.
  191. pThisDisplay->pGLInfo = pGLInfo;
  192. pThisDisplay->control = (FLATPTR) pGLInfo->pRegs;
  193. // NT uses offsets for its memory addresses
  194. pThisDisplay->dwScreenFlatAddr = 0;
  195. pThisDisplay->dwLocalBuffer = 0;
  196. __DDE_BuildPixelFormat( pThisDisplay,
  197. (LPGLINTINFO) pThisDisplay->pGLInfo,
  198. &pThisDisplay->ddpfDisplay );
  199. // Setup the display size information
  200. // dwScreenWidth, dwScreenHeight = current resolution
  201. // cxMemory = Pixels across for one scanline
  202. // (not necessarily the same as the screen width)
  203. // cyMemory = Scanline height of the memory
  204. // dwScreenStart = First visible line of display
  205. pThisDisplay->dwScreenWidth = pGLInfo->dwScreenWidth;
  206. pThisDisplay->dwScreenHeight = pGLInfo->dwScreenHeight;
  207. pThisDisplay->cxMemory = pGLInfo->dwScreenWidth;
  208. pThisDisplay->dwScreenStart = pThisDisplay->dwScreenFlatAddr +
  209. pGLInfo->dwScreenBase;
  210. // Usefull constants used during blits.
  211. if (pThisDisplay->ddpfDisplay.dwRGBBitCount == 24)
  212. {
  213. // The driver will detect these strange values and handle appropriately
  214. pThisDisplay->bPixShift = 4;
  215. pThisDisplay->bBppShift = 4;
  216. pThisDisplay->dwBppMask = 4;
  217. pThisDisplay->cyMemory = pGLInfo->ddFBSize /
  218. (pThisDisplay->dwScreenWidth * 3);
  219. }
  220. else
  221. {
  222. // = 2,1,0 for 32,16,8 depth. Shifts needed to calculate bytes/pixel
  223. pThisDisplay->bPixShift =
  224. (BYTE)pThisDisplay->ddpfDisplay.dwRGBBitCount >> 4;
  225. // = 0,1,2 for 32/16/8.
  226. pThisDisplay->bBppShift = 2 - pThisDisplay->bPixShift;
  227. // = 3,1,0 for 8,16,32 bpp
  228. pThisDisplay->dwBppMask = 3 >> pThisDisplay->bPixShift;
  229. pThisDisplay->cyMemory =
  230. pGLInfo->ddFBSize /
  231. (pThisDisplay->dwScreenWidth <<
  232. (pThisDisplay->ddpfDisplay.dwRGBBitCount >> 4));
  233. }
  234. // On Windows NT, we manage a region of memory starting from 0
  235. //(all pointers are offsets from the start of the mapped memory)
  236. dwMemStart = pGLInfo->dwOffscreenBase;
  237. dwMemEnd = pGLInfo->ddFBSize - 1;
  238. // Round up the start pointer and round down the end pointer
  239. dwMemStart = (dwMemStart + 3) & ~3;
  240. dwMemEnd = dwMemEnd & ~3;
  241. // Now make the end pointer inclusive
  242. dwMemEnd -= 1;
  243. DISPDBG((DBGLVL,"Heap Attributes:"));
  244. DISPDBG((DBGLVL," Start of Heap Memory: 0x%lx",
  245. pThisDisplay->LocalVideoHeap0Info.dwMemStart));
  246. DISPDBG((DBGLVL," End of Heap Memory: 0x%lx",
  247. pThisDisplay->LocalVideoHeap0Info.dwMemEnd));
  248. // If we already have a heap setup and the mode has changed
  249. // we free the Heap manager
  250. if (pThisDisplay->bDDHeapManager)
  251. {
  252. if (pThisDisplay->bResetMode)
  253. {
  254. // The mode has been changed.
  255. // We need to free the allocator and re-create it
  256. _DX_LIN_UnInitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info);
  257. // Start the allocator off again.
  258. _DX_LIN_InitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info,
  259. dwMemStart,
  260. dwMemEnd);
  261. }
  262. }
  263. else
  264. {
  265. // This must be the first instance of a created driver,
  266. // so create the Heap and remember that it is created.
  267. _DX_LIN_InitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info,
  268. dwMemStart,
  269. dwMemEnd);
  270. pThisDisplay->bDDHeapManager = TRUE;
  271. }
  272. if(ppdev->flStatus & ENABLE_LINEAR_HEAP)
  273. {
  274. // save away the heap info we really need, we won't actually
  275. // enable the DX managed heap until we get a
  276. // DrvNotify(DN_DRAWING_BEGIN)
  277. ppdev->heap.pvmLinearHeap = &pThisDisplay->LocalVideoHeap0Info;
  278. ppdev->heap.cLinearHeaps = 1;
  279. }
  280. return TRUE;
  281. } // __DDE_bSetupDDStructs
  282. //-----------------------------------------------------------------------------
  283. //
  284. // ***************************WIN NT ONLY**********************************
  285. //
  286. // __DDE_bDestroyDDStructs
  287. //
  288. // Disable the linear allocator.
  289. //
  290. //-----------------------------------------------------------------------------
  291. BOOL
  292. __DDE_bDestroyDDStructs (
  293. P3_THUNKEDDATA* pThisDisplay )
  294. {
  295. // Release the linear allocator
  296. if (pThisDisplay->bDDHeapManager)
  297. {
  298. _DX_LIN_UnInitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info);
  299. }
  300. // 3D Heap manager not available.
  301. pThisDisplay->bDDHeapManager = FALSE;
  302. // Reset the driver version to 0 so it will be filled in again.
  303. pThisDisplay->dwDXVersion = 0;
  304. return TRUE;
  305. } // __DDE_bDestroyDDStructs
  306. //-----------------------------------------------------------------------------
  307. //
  308. // ***************************WIN NT ONLY**********************************
  309. //
  310. // _DD_DDE_CreatePPDEV
  311. //
  312. // These functions are called in sync with the creation/destruction of the pDev
  313. //
  314. //-----------------------------------------------------------------------------
  315. BOOL
  316. _DD_DDE_CreatePPDEV(
  317. PDEV* ppdev)
  318. {
  319. P3_THUNKEDDATA* pThisDisplay;
  320. DISPDBG((DBGLVL,"*** In _DD_DDE_CreatePPDEV"));
  321. ASSERTDD(ppdev->thunkData == NULL,
  322. "ERROR: thunkData already created for this pDev??");
  323. // initialize the DX context which will be used by the display driver
  324. // context switcher. We need a reference count because there is a case
  325. // when a second, temporary, context would otherwise be created (when
  326. // enabling the second adapter in a m-monitor system), first scrubbing
  327. // out the old context ID, then invalidating the new one when it is
  328. // deleted!
  329. ppdev->DDContextID = -1;
  330. ppdev->DDContextRefCount = 0;
  331. // Allocate our ppdev
  332. ppdev->thunkData = (PVOID)HEAP_ALLOC(HEAP_ZERO_MEMORY,
  333. sizeof(P3_THUNKEDDATA),
  334. ALLOC_TAG_DX(D));
  335. if (ppdev->thunkData == NULL)
  336. {
  337. DISPDBG((ERRLVL, "_DD_DDE_CreatePPDEV: thunkdata alloc failed"));
  338. return (FALSE);
  339. }
  340. // Our ppdev is called pThisDisplay
  341. pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
  342. pThisDisplay->ppdev = ppdev;
  343. pThisDisplay->pGLInfo = (PVOID)HEAP_ALLOC(HEAP_ZERO_MEMORY,
  344. sizeof(GlintInfo),
  345. ALLOC_TAG_DX(E));
  346. if (pThisDisplay->pGLInfo == NULL)
  347. {
  348. DISPDBG((ERRLVL, "_DD_DDE_CreatePPDEV: pGLInfo alloc failed"));
  349. EngFreeMem (pThisDisplay);
  350. ppdev->thunkData = NULL;
  351. return (FALSE);
  352. }
  353. //@@BEGIN_DDKSPLIT
  354. // W9X DX version is setup in the display driver.
  355. //@@END_DDKSPLIT
  356. // On Windows W2000 DX is always at least DX7
  357. pThisDisplay->dwDXVersion = DX7_RUNTIME;
  358. GetChipInfoForDDraw(ppdev,
  359. &pThisDisplay->pGLInfo->dwRenderChipID,
  360. &pThisDisplay->pGLInfo->dwRenderChipRev,
  361. &pThisDisplay->pGLInfo->dwRenderFamily,
  362. &pThisDisplay->pGLInfo->dwGammaRev);
  363. DISPDBG((DBGLVL,"RenderChip: 0x%x, RenderFamily: 0x%x",
  364. pThisDisplay->pGLInfo->dwRenderChipID,
  365. pThisDisplay->pGLInfo->dwRenderFamily));
  366. return TRUE;
  367. } // _DD_DDE_CreatePPDEV
  368. //-----------------------------------------------------------------------------
  369. //
  370. // ***************************WIN NT ONLY**********************************
  371. //
  372. // _DD_DDE_ResetPPDEV
  373. //
  374. //-----------------------------------------------------------------------------
  375. void _DD_DDE_ResetPPDEV(PDEV* ppdevOld, PDEV* ppdevNew)
  376. {
  377. P3_THUNKEDDATA* pThisDisplayOld = (P3_THUNKEDDATA*)ppdevOld->thunkData;
  378. P3_THUNKEDDATA* pThisDisplayNew = (P3_THUNKEDDATA*)ppdevNew->thunkData;
  379. DISPDBG((DBGLVL,"_DD_DDE_ResetPPDEV: "
  380. "pThisDispayOld: 0x%x, pThisDisplayNew: 0x%x",
  381. pThisDisplayOld, pThisDisplayNew));
  382. } // _DD_DDE_ResetPPDEV
  383. //-----------------------------------------------------------------------------
  384. //
  385. // ***************************WIN NT ONLY**********************************
  386. //
  387. // _DD_DDE_DestroyPPDEV
  388. //
  389. //-----------------------------------------------------------------------------
  390. void _DD_DDE_DestroyPPDEV(PDEV* ppdev)
  391. {
  392. P3_THUNKEDDATA* pThisDisplay = (P3_THUNKEDDATA*)ppdev->thunkData;
  393. #if DBG
  394. g_pThisTemp = NULL;
  395. #endif
  396. if (pThisDisplay)
  397. {
  398. // The 32 bit side will have allocated memory for use as global
  399. // D3D/DD Driver data. Free it if it is there
  400. if (pThisDisplay->pD3DHALCallbacks16)
  401. {
  402. SHARED_HEAP_FREE(&pThisDisplay->pD3DHALCallbacks16,
  403. &pThisDisplay->pD3DHALCallbacks32,
  404. TRUE);
  405. DISPDBG((DBGLVL,"Freed pThisDisplay->pD3DHALCallbacks32"));
  406. }
  407. if (pThisDisplay->pD3DDriverData16)
  408. {
  409. SHARED_HEAP_FREE(&pThisDisplay->pD3DDriverData16,
  410. &pThisDisplay->pD3DDriverData32,
  411. TRUE);
  412. DISPDBG((DBGLVL,"Freed pThisDisplay->pD3DDriverData32"));
  413. }
  414. pThisDisplay->lpD3DGlobalDriverData = 0;
  415. pThisDisplay->lpD3DHALCallbacks = 0;
  416. if (pThisDisplay->pGLInfo)
  417. {
  418. EngFreeMem (pThisDisplay->pGLInfo);
  419. pThisDisplay->pGLInfo = NULL;
  420. DISPDBG((DBGLVL,"Freed pThisDisplay->pGLInfo"));
  421. }
  422. EngFreeMem (pThisDisplay);
  423. pThisDisplay = NULL;
  424. DISPDBG((DBGLVL,"Freed pThisDisplay"));
  425. }
  426. // Clear the pointer
  427. ppdev->thunkData = NULL;
  428. } // _DD_DDE_DestroyPPDEV
  429. //-----------------------------------------------------------------------------
  430. //
  431. // ***************************WIN NT ONLY**********************************
  432. //
  433. // _DD_DDE_vAssertModeDirectDraw
  434. //
  435. // This function is called by enable.c when entering or leaving the
  436. // DOS full-screen character mode.
  437. //
  438. //-----------------------------------------------------------------------------
  439. VOID
  440. _DD_DDE_vAssertModeDirectDraw(
  441. PDEV* ppdev,
  442. BOOL bEnabled)
  443. {
  444. P3_THUNKEDDATA* pThisDisplay = (P3_THUNKEDDATA*)ppdev->thunkData;
  445. DISPDBG((DBGLVL, "_DD_DDE_vAssertModeDirectDraw: enter"));
  446. #if DX7_TEXMANAGEMENT
  447. // Mark all managed surfaces as dirty as we've lost
  448. // everything living in the videomemory
  449. _DD_TM_EvictAllManagedTextures(pThisDisplay);
  450. #endif
  451. } // _DD_DDE_vAssertModeDirectDraw
  452. //-----------------------------------------------------------------------------
  453. //
  454. // ***************************WIN NT ONLY**********************************
  455. //
  456. // _DD_DDE_bEnableDirectDraw
  457. //
  458. // This function is called by enable.c when the mode is first initialized,
  459. // right after the miniport does the mode-set.
  460. //
  461. //-----------------------------------------------------------------------------
  462. BOOL _DD_DDE_bEnableDirectDraw(
  463. PDEV* ppdev)
  464. {
  465. DISPDBG((DBGLVL, "_DD_DDE_bEnableDirectDraw: enter"));
  466. // DirectDraw is all set to be used on this card:
  467. ppdev->flStatus |= STAT_DIRECTDRAW;
  468. return(TRUE);
  469. } // _DD_DDE_bEnableDirectDraw
  470. //-----------------------------------------------------------------------------
  471. //
  472. // ***************************WIN NT ONLY**********************************
  473. //
  474. // _DD_DDE_vDisableDirectDraw
  475. //
  476. // This function is called by enable.c when the driver is shutting down.
  477. //
  478. //-----------------------------------------------------------------------------
  479. VOID _DD_DDE_vDisableDirectDraw(
  480. PDEV* ppdev)
  481. {
  482. DISPDBG((DBGLVL, "_DD_DDE_vDisableDirectDraw: enter"));
  483. } // _DD_DDE_vDisableDirectDraw
  484. //-----------------------------Public Routine----------------------------------
  485. //
  486. // ***************************WIN NT ONLY**********************************
  487. //
  488. // DrvEnableDirectDraw
  489. //
  490. // Enables hardware for DirectDraw use.
  491. //
  492. // GDI calls DrvEnableDirectDraw to obtain pointers to the DirectDraw callbacks
  493. // that the driver supports. The driver should set the function pointer members
  494. // of DD_CALLBACKS, DD_SURFACECALLBACKS, and DD_PALETTECALLBACKS to point to
  495. // those functions that it implements. A driver should also set the
  496. // corresponding bit fields in the dwFlags members of these structures for all
  497. // supported callbacks.
  498. //
  499. // A driver's DrvEnableDirectDraw implementation can also dedicate hardware
  500. // resources such as display memory for use by DirectDraw only.
  501. //
  502. // DrvEnableDirectDraw returns TRUE if it succeeds; otherwise, it returns FALSE
  503. //
  504. // Parameters
  505. //
  506. // dhpdev
  507. // Handle to the PDEV returned by the driver's DrvEnablePDEV routine.
  508. // pCallBacks
  509. // Points to the DD_CALLBACKS structure to be initialized by the
  510. // driver.
  511. // pSurfaceCallBacks
  512. // Points to the DD_SURFACECALLBACKS structure to be initialized by
  513. // the driver.
  514. // pPaletteCallBacks
  515. // Points to the DD_PALETTECALLBACKS structure to be initialized by
  516. // the driver.
  517. //
  518. //-----------------------------------------------------------------------------
  519. BOOL DrvEnableDirectDraw(
  520. DHPDEV dhpdev,
  521. DD_CALLBACKS* pCallBacks,
  522. DD_SURFACECALLBACKS* pSurfaceCallBacks,
  523. DD_PALETTECALLBACKS* pPaletteCallBacks)
  524. {
  525. PDEV* ppdev;
  526. BOOL bRet;
  527. DWORD dwResult;
  528. P3_THUNKEDDATA* pThisDisplay;
  529. DWORD *theVBlankThing, *bOverlayEnabled;
  530. DWORD *VBLANKUpdateOverlay;
  531. DWORD *VBLANKUpdateOverlayWidth;
  532. DWORD *VBLANKUpdateOverlayHeight;
  533. DWORD Buffers;
  534. ppdev = (PDEV*) dhpdev;
  535. pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
  536. if (!bSetupOffscreenForDDraw (FALSE,
  537. ppdev,
  538. &theVBlankThing,
  539. &bOverlayEnabled,
  540. &VBLANKUpdateOverlay,
  541. &VBLANKUpdateOverlayWidth,
  542. &VBLANKUpdateOverlayHeight))
  543. {
  544. DISPDBG((ERRLVL, "DrvEnableDirectDraw: "
  545. "bSetupOffscreenForDDraw failed, but continuing"));
  546. //return (FALSE);
  547. }
  548. pThisDisplay->VBlankStatusPtr = theVBlankThing;
  549. pThisDisplay->bOverlayEnabled = bOverlayEnabled;
  550. pThisDisplay->bVBLANKUpdateOverlay = VBLANKUpdateOverlay;
  551. pThisDisplay->VBLANKUpdateOverlayWidth = VBLANKUpdateOverlayWidth;
  552. pThisDisplay->VBLANKUpdateOverlayHeight = VBLANKUpdateOverlayHeight;
  553. #if DBG
  554. // Read in the registry variable for the debug level
  555. {
  556. // Get the Debuglevel for DirectX
  557. bRet = GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.Debug", &dwResult);
  558. if (bRet == TRUE)
  559. {
  560. P3R3DX_DebugLevel = (LONG)dwResult;
  561. }
  562. else
  563. {
  564. P3R3DX_DebugLevel = 0;
  565. }
  566. DISPDBG((WRNLVL,"Setting DebugLevel to 0x%x", P3R3DX_DebugLevel));
  567. }
  568. #endif
  569. // Create context with >2 sub-buffers for Interupt driven DMA.
  570. bRet =GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.SubBuffers", &dwResult);
  571. if ((dwResult == 0) || (bRet == FALSE))
  572. {
  573. // Default
  574. Buffers = DEFAULT_SUBBUFFERS;
  575. }
  576. else
  577. {
  578. if (dwResult > MAX_SUBBUFFERS)
  579. {
  580. Buffers = MAX_SUBBUFFERS;
  581. }
  582. else
  583. {
  584. Buffers = dwResult;
  585. }
  586. if (Buffers < 2)
  587. {
  588. Buffers = 2;
  589. }
  590. }
  591. pThisDisplay->pGLInfo->dw3DDMABufferSize = 0;
  592. pThisDisplay->pGLInfo->dw3DDMABufferPhys = 0;
  593. pThisDisplay->pGLInfo->dw3DDMABufferVirt = 0;
  594. // Allocate a DMA Buffer on Win2K
  595. DDGetFreeDMABuffer(&pThisDisplay->pGLInfo->dw3DDMABufferPhys,
  596. &pThisDisplay->pGLInfo->dw3DDMABufferVirt,
  597. &pThisDisplay->pGLInfo->dw3DDMABufferSize);
  598. if (pThisDisplay->pGLInfo->dw3DDMABufferSize != 0)
  599. {
  600. DISPDBG((DBGLVL,"Allocated DMA Buffer:- "
  601. "Phys:0x%x, Virt:0x%x, Size:0x%x",
  602. pThisDisplay->pGLInfo->dw3DDMABufferPhys,
  603. pThisDisplay->pGLInfo->dw3DDMABufferVirt,
  604. pThisDisplay->pGLInfo->dw3DDMABufferSize));
  605. }
  606. else
  607. {
  608. DISPDBG((WRNLVL,"Failed to allocate DMA Buffer!"));
  609. }
  610. if(ppdev->DDContextID == -1)
  611. {
  612. // we don't have a DDraw context: create one now
  613. ppdev->DDContextID = GlintAllocateNewContext(ppdev,
  614. NULL,
  615. 0,
  616. Buffers,
  617. NULL,
  618. ContextType_None);
  619. if(ppdev->DDContextID != -1)
  620. {
  621. ++ppdev->DDContextRefCount;
  622. DISPDBG((DBGLVL, "<%13s, %4d>: DrvEnableDirectDraw: "
  623. "Created DDraw context, current DX context "
  624. "count = %d for ppdev %p",
  625. __FILE__, __LINE__,
  626. ppdev->DDContextRefCount, ppdev));
  627. }
  628. }
  629. if (ppdev->DDContextID < 0)
  630. {
  631. DISPDBG((ERRLVL, "ERROR: failed to allocate DDRAW context"));
  632. return(FALSE);
  633. }
  634. DISPDBG((DBGLVL," Created DD Register context: 0x%x",
  635. ppdev->DDContextID));
  636. if (!__DDE_bSetupDDStructs (pThisDisplay, TRUE))
  637. {
  638. vGlintFreeContext (ppdev, ppdev->DDContextID);
  639. DISPDBG((ERRLVL, "ERROR: DrvEnableDirectDraw: "
  640. "__DDE_bSetupDDStructs failed"));
  641. return (FALSE);
  642. }
  643. if (!_DD_InitDDHAL32Bit (pThisDisplay))
  644. {
  645. vGlintFreeContext (ppdev, ppdev->DDContextID);
  646. DISPDBG((ERRLVL, "ERROR: DrvEnableDirectDraw: "
  647. "_DD_InitDDHAL32Bit failed"));
  648. return (FALSE);
  649. }
  650. // Set the flag that says we have to handle a mode change.
  651. // This will cause the chip to be initialised properly at the
  652. // right time.
  653. pThisDisplay->bResetMode = TRUE;
  654. pThisDisplay->bStartOfDay = TRUE;
  655. pThisDisplay->pGLInfo->dwDirectXState = DIRECTX_LASTOP_UNKNOWN;
  656. // Fill in the function pointers at start of day. We copy these from
  657. // the Initialisation done in _DD_InitDDHAL32Bit. It's OK to do this
  658. // because on a Windows NT compile the structures should match
  659. memcpy(pCallBacks,
  660. &pThisDisplay->DDHALCallbacks,
  661. sizeof(DD_CALLBACKS));
  662. memcpy(pSurfaceCallBacks,
  663. &pThisDisplay->DDSurfCallbacks,
  664. sizeof(DD_SURFACECALLBACKS));
  665. // Note that we don't call 'vGetDisplayDuration' here, for a couple of
  666. // reasons:
  667. //
  668. // o Because the system is already running, it would be disconcerting
  669. // to pause the graphics for a good portion of a second just to read
  670. // the refresh rate;
  671. // o More importantly, we may not be in graphics mode right now.
  672. //
  673. // For both reasons, we always measure the refresh rate when we switch
  674. // to a new mode.
  675. return(TRUE);
  676. } // DrvEnableDirectDraw
  677. //-----------------------------Public Routine----------------------------------
  678. //
  679. // ***************************WIN NT ONLY**********************************
  680. //
  681. // DrvDisableDirectDraw
  682. //
  683. // Disables hardware for DirectDraw use.
  684. //
  685. // GDI calls DrvDisableDirectDraw when the last DirectDraw application has
  686. // finished running. A driver's DrvDisableDirectDraw implementation should
  687. // clean up any software resources and reclaim any hardware resources that
  688. // the driver dedicated to DirectDraw in DrvEnableDirectDraw.
  689. //
  690. // Parameters
  691. // dhpdev
  692. // Handle to the PDEV that was returned by the driver's
  693. // DrvEnablePDEV routine.
  694. //
  695. //-----------------------------------------------------------------------------
  696. VOID
  697. DrvDisableDirectDraw(
  698. DHPDEV dhpdev)
  699. {
  700. PDEV* ppdev;
  701. P3_THUNKEDDATA* pThisDisplay;
  702. ppdev = (PDEV*) dhpdev;
  703. pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
  704. // Only do all this stuff if we have not already been disabled.
  705. // Note that when running NT4 without SP3, this function can be called
  706. // more times than DrvEnableDirectDraw.
  707. if (pThisDisplay != NULL)
  708. {
  709. // Re-enable GDI off-screen bitmaps
  710. (void) bSetupOffscreenForDDraw (TRUE,
  711. ppdev,
  712. NULL,
  713. NULL,
  714. NULL,
  715. NULL,
  716. NULL);
  717. // Free all memory
  718. (void) __DDE_bDestroyDDStructs (pThisDisplay);
  719. if(ppdev->DDContextRefCount > 0)
  720. {
  721. if(--ppdev->DDContextRefCount == 0)
  722. {
  723. vGlintFreeContext (ppdev, ppdev->DDContextID);
  724. DISPDBG((DBGLVL,"Freed DDraw context: 0x%x",
  725. ppdev->DDContextID));
  726. ppdev->DDContextID = -1;
  727. DISPDBG((DBGLVL, "<%13s, %4d>: DrvDisableDirectDraw:"
  728. " Deleted DDraw context, current DX context"
  729. " count = %d for ppdev %p",
  730. __FILE__, __LINE__,
  731. ppdev->DDContextRefCount, ppdev));
  732. }
  733. }
  734. DDFreeDMABuffer((void*)(ULONG_PTR)pThisDisplay->pGLInfo->dw3DDMABufferPhys);
  735. }
  736. } // DrvDisableDirectDraw
  737. #endif // WNT_DDRAW