Source code of Windows XP (NT5)
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.

410 lines
15 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: ddraw64.c
  3. *
  4. * Implements all the common DirectDraw components for the
  5. * ATI MACH 64/32/32 Memory mapped driver.
  6. *
  7. * Copyright (c) 1995-1996 Microsoft Corporation
  8. \**************************************************************************/
  9. #include "precomp.h"
  10. extern BOOL DrvGetDirectDrawInfo32I( DHPDEV dhpdev,DD_HALINFO* pHalInfo,DWORD* pdwNumHeaps,VIDEOMEMORY* pvmList,
  11. DWORD* pdwNumFourCC,DWORD* pdwFourCC);
  12. extern BOOL DrvGetDirectDrawInfo32M( DHPDEV dhpdev,DD_HALINFO* pHalInfo,DWORD* pdwNumHeaps,VIDEOMEMORY* pvmList,
  13. DWORD* pdwNumFourCC,DWORD* pdwFourCC);
  14. extern BOOL DrvGetDirectDrawInfo64( DHPDEV dhpdev,DD_HALINFO* pHalInfo,DWORD* pdwNumHeaps,VIDEOMEMORY* pvmList,
  15. DWORD* pdwNumFourCC,DWORD* pdwFourCC);
  16. extern VOID vGetDisplayDuration32I(PDEV* ppdev);
  17. extern DWORD DdBlt32I(PDD_BLTDATA lpBlt);
  18. extern DWORD DdFlip32I(PDD_FLIPDATA lpFlip);
  19. extern DWORD DdLock32I(PDD_LOCKDATA lpLock);
  20. extern DWORD DdGetBltStatus32I(PDD_GETBLTSTATUSDATA lpGetBltStatus);
  21. extern DWORD DdGetFlipStatus32I(PDD_GETFLIPSTATUSDATA lpGetFlipStatus);
  22. extern DWORD DdWaitForVerticalBlank32I(PDD_WAITFORVERTICALBLANKDATA lpWaitForVerticalBlank);
  23. extern DWORD DdGetScanLine32I(PDD_GETSCANLINEDATA lpGetScanLine);
  24. extern VOID vGetDisplayDuration32M(PDEV* ppdev);
  25. extern DWORD DdBlt32M(PDD_BLTDATA lpBlt);
  26. extern DWORD DdFlip32M(PDD_FLIPDATA lpFlip);
  27. extern DWORD DdLock32M(PDD_LOCKDATA lpLock);
  28. extern DWORD DdGetBltStatus32M(PDD_GETBLTSTATUSDATA lpGetBltStatus);
  29. extern DWORD DdGetFlipStatus32M(PDD_GETFLIPSTATUSDATA lpGetFlipStatus);
  30. extern DWORD DdWaitForVerticalBlank32M(PDD_WAITFORVERTICALBLANKDATA lpWaitForVerticalBlank);
  31. extern DWORD DdGetScanLine32M(PDD_GETSCANLINEDATA lpGetScanLine);
  32. extern VOID vGetDisplayDuration64(PDEV* ppdev);
  33. extern DWORD DdBlt64(PDD_BLTDATA lpBlt);
  34. extern DWORD DdFlip64(PDD_FLIPDATA lpFlip);
  35. extern DWORD DdLock64(PDD_LOCKDATA lpLock);
  36. extern DWORD DdGetBltStatus64(PDD_GETBLTSTATUSDATA lpGetBltStatus);
  37. extern DWORD DdGetFlipStatus64(PDD_GETFLIPSTATUSDATA lpGetFlipStatus);
  38. extern DWORD DdWaitForVerticalBlank64(PDD_WAITFORVERTICALBLANKDATA lpWaitForVerticalBlank);
  39. extern DWORD DdGetScanLine64(PDD_GETSCANLINEDATA lpGetScanLine);
  40. /******************************Public*Routine******************************\
  41. * DWORD DdMapMemory
  42. *
  43. * This is a new DDI call specific to Windows NT that is used to map
  44. * or unmap all the application modifiable portions of the frame buffer
  45. * into the specified process's address space.
  46. *
  47. \**************************************************************************/
  48. DWORD DdMapMemory(
  49. PDD_MAPMEMORYDATA lpMapMemory)
  50. {
  51. PDEV* ppdev;
  52. VIDEO_SHARE_MEMORY ShareMemory;
  53. VIDEO_SHARE_MEMORY_INFORMATION ShareMemoryInformation;
  54. DWORD ReturnedDataLength;
  55. ppdev = (PDEV*) lpMapMemory->lpDD->dhpdev;
  56. if (lpMapMemory->bMap)
  57. {
  58. ShareMemory.ProcessHandle = lpMapMemory->hProcess;
  59. // 'RequestedVirtualAddress' isn't actually used for the SHARE IOCTL:
  60. ShareMemory.RequestedVirtualAddress = 0;
  61. // We map in starting at the top of the frame buffer:
  62. ShareMemory.ViewOffset = 0;
  63. // We map down to the end of the frame buffer.
  64. //
  65. // Note: There is a 64k granularity on the mapping (meaning that
  66. // we have to round up to 64k).
  67. //
  68. // Note: If there is any portion of the frame buffer that must
  69. // not be modified by an application, that portion of memory
  70. // MUST NOT be mapped in by this call. This would include
  71. // any data that, if modified by a malicious application,
  72. // would cause the driver to crash. This could include, for
  73. // example, any DSP code that is kept in off-screen memory.
  74. ShareMemory.ViewSize
  75. = ROUND_UP_TO_64K(ppdev->cyMemory * ppdev->lDelta);
  76. DISPDBG((10, "Share memory size %x %d",ShareMemory.ViewSize,ShareMemory.ViewSize));
  77. if (EngDeviceIoControl(ppdev->hDriver,
  78. IOCTL_VIDEO_SHARE_VIDEO_MEMORY,
  79. &ShareMemory,
  80. sizeof(VIDEO_SHARE_MEMORY),
  81. &ShareMemoryInformation,
  82. sizeof(VIDEO_SHARE_MEMORY_INFORMATION),
  83. &ReturnedDataLength))
  84. {
  85. DISPDBG((10, "Failed IOCTL_VIDEO_SHARE_MEMORY"));
  86. lpMapMemory->ddRVal = DDERR_GENERIC;
  87. return(DDHAL_DRIVER_HANDLED);
  88. }
  89. lpMapMemory->fpProcess =(FLATPTR)ShareMemoryInformation.VirtualAddress;
  90. }
  91. else
  92. {
  93. ShareMemory.ProcessHandle = lpMapMemory->hProcess;
  94. ShareMemory.ViewOffset = 0;
  95. ShareMemory.ViewSize = 0;
  96. ShareMemory.RequestedVirtualAddress = (VOID*) lpMapMemory->fpProcess;
  97. if (EngDeviceIoControl(ppdev->hDriver,
  98. IOCTL_VIDEO_UNSHARE_VIDEO_MEMORY,
  99. &ShareMemory,
  100. sizeof(VIDEO_SHARE_MEMORY),
  101. NULL,
  102. 0,
  103. &ReturnedDataLength))
  104. {
  105. RIP("Failed IOCTL_VIDEO_UNSHARE_MEMORY");
  106. }
  107. }
  108. lpMapMemory->ddRVal = DD_OK;
  109. return(DDHAL_DRIVER_HANDLED);
  110. }
  111. /******************************Public*Routine******************************\
  112. * BOOL DrvGetDirectDrawInfo
  113. *
  114. * Will be called before DrvEnableDirectDraw is called.
  115. *
  116. \**************************************************************************/
  117. BOOL DrvGetDirectDrawInfo(
  118. DHPDEV dhpdev,
  119. DD_HALINFO* pHalInfo,
  120. DWORD* pdwNumHeaps,
  121. VIDEOMEMORY* pvmList, // Will be NULL on first call
  122. DWORD* pdwNumFourCC,
  123. DWORD* pdwFourCC) // Will be NULL on first call
  124. {
  125. PDEV* ppdev;
  126. ppdev = (PDEV*) dhpdev;
  127. // if no APERATURE then we are a MACH8 and have no DDraw support
  128. if (ppdev->iAperture == APERTURE_NONE)
  129. {
  130. return FALSE;
  131. }
  132. // we can't use DirectDraw on a banked device because of a conflict
  133. // over who owns the bank registers between VideoPortMapBankedMemory
  134. // and the display driver
  135. if (!(ppdev->flCaps & CAPS_LINEAR_FRAMEBUFFER))
  136. {
  137. return FALSE;
  138. }
  139. if (ppdev->iMachType == MACH_MM_32)
  140. {
  141. // Can do memory-mapped IO:
  142. return(DrvGetDirectDrawInfo32M(dhpdev,pHalInfo,pdwNumHeaps,pvmList,pdwNumFourCC,pdwFourCC));
  143. }
  144. else if (ppdev->iMachType == MACH_IO_32)
  145. {
  146. return(DrvGetDirectDrawInfo32I(dhpdev,pHalInfo,pdwNumHeaps,pvmList,pdwNumFourCC,pdwFourCC));
  147. }
  148. else
  149. {
  150. // MACH 64
  151. return(DrvGetDirectDrawInfo64(dhpdev,pHalInfo,pdwNumHeaps,pvmList,pdwNumFourCC,pdwFourCC));
  152. }
  153. }
  154. /******************************Public*Routine******************************\
  155. * BOOL DrvEnableDirectDraw
  156. *
  157. * This function is called by GDI to enable DirectDraw when a DirectDraw
  158. * program is started and DirectDraw is not already active.
  159. *
  160. \**************************************************************************/
  161. BOOL DrvEnableDirectDraw(
  162. DHPDEV dhpdev,
  163. DD_CALLBACKS* pCallBacks,
  164. DD_SURFACECALLBACKS* pSurfaceCallBacks,
  165. DD_PALETTECALLBACKS* pPaletteCallBacks)
  166. {
  167. PDEV* ppdev;
  168. ppdev = (PDEV*) dhpdev;
  169. if (ppdev->iMachType == MACH_MM_32)
  170. {
  171. pSurfaceCallBacks->Blt = DdBlt32M;
  172. pSurfaceCallBacks->Flip = DdFlip32M;
  173. pSurfaceCallBacks->Lock = DdLock32M;
  174. pSurfaceCallBacks->GetBltStatus = DdGetBltStatus32M;
  175. pSurfaceCallBacks->GetFlipStatus = DdGetFlipStatus32M;
  176. if (ppdev->iBitmapFormat >= BMF_24BPP)
  177. {
  178. pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_LOCK;
  179. }
  180. else
  181. {
  182. pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_BLT
  183. | DDHAL_SURFCB32_FLIP
  184. | DDHAL_SURFCB32_LOCK
  185. | DDHAL_SURFCB32_GETBLTSTATUS
  186. | DDHAL_SURFCB32_GETFLIPSTATUS;
  187. }
  188. pCallBacks->WaitForVerticalBlank = DdWaitForVerticalBlank32M;
  189. pCallBacks->GetScanLine = DdGetScanLine32M;
  190. pCallBacks->MapMemory = DdMapMemory;
  191. pCallBacks->dwFlags = DDHAL_CB32_WAITFORVERTICALBLANK
  192. | DDHAL_CB32_GETSCANLINE
  193. | DDHAL_CB32_MAPMEMORY;
  194. }
  195. else if (ppdev->iMachType == MACH_IO_32 )
  196. {
  197. pSurfaceCallBacks->Blt = DdBlt32I;
  198. pSurfaceCallBacks->Flip = DdFlip32I;
  199. pSurfaceCallBacks->Lock = DdLock32I;
  200. pSurfaceCallBacks->GetBltStatus = DdGetBltStatus32I;
  201. pSurfaceCallBacks->GetFlipStatus = DdGetFlipStatus32I;
  202. if (ppdev->iBitmapFormat >= BMF_24BPP)
  203. {
  204. pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_LOCK;
  205. }
  206. else
  207. {
  208. pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_BLT
  209. | DDHAL_SURFCB32_FLIP
  210. | DDHAL_SURFCB32_LOCK
  211. | DDHAL_SURFCB32_GETBLTSTATUS
  212. | DDHAL_SURFCB32_GETFLIPSTATUS;
  213. }
  214. pCallBacks->WaitForVerticalBlank = DdWaitForVerticalBlank32I;
  215. pCallBacks->GetScanLine = DdGetScanLine32I;
  216. pCallBacks->MapMemory = DdMapMemory;
  217. pCallBacks->dwFlags = DDHAL_CB32_WAITFORVERTICALBLANK
  218. | DDHAL_CB32_GETSCANLINE
  219. | DDHAL_CB32_MAPMEMORY;
  220. }
  221. else
  222. { // MACH 64
  223. pSurfaceCallBacks->Blt = DdBlt64;
  224. pSurfaceCallBacks->Flip = DdFlip64;
  225. pSurfaceCallBacks->Lock = DdLock64;
  226. pSurfaceCallBacks->GetBltStatus = DdGetBltStatus64;
  227. pSurfaceCallBacks->GetFlipStatus = DdGetFlipStatus64;
  228. if (ppdev->iBitmapFormat >= BMF_24BPP)
  229. {
  230. pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_LOCK;
  231. }
  232. else
  233. {
  234. pSurfaceCallBacks->dwFlags = DDHAL_SURFCB32_BLT
  235. | DDHAL_SURFCB32_FLIP
  236. | DDHAL_SURFCB32_LOCK
  237. | DDHAL_SURFCB32_GETBLTSTATUS
  238. | DDHAL_SURFCB32_GETFLIPSTATUS;
  239. }
  240. pCallBacks->WaitForVerticalBlank = DdWaitForVerticalBlank64;
  241. pCallBacks->GetScanLine = DdGetScanLine64;
  242. pCallBacks->MapMemory = DdMapMemory;
  243. pCallBacks->dwFlags = DDHAL_CB32_WAITFORVERTICALBLANK
  244. | DDHAL_CB32_GETSCANLINE
  245. | DDHAL_CB32_MAPMEMORY;
  246. }
  247. // Note that we don't call 'vGetDisplayDuration' here, for a couple of
  248. // reasons:
  249. //
  250. // o Because the system is already running, it would be disconcerting
  251. // to pause the graphics for a good portion of a second just to read
  252. // the refresh rate;
  253. // o More importantly, we may not be in graphics mode right now.
  254. //
  255. // For both reasons, we always measure the refresh rate when we switch
  256. // to a new mode.
  257. return(TRUE);
  258. }
  259. /******************************Public*Routine******************************\
  260. * BOOL DrvDisableDirectDraw
  261. *
  262. * This function is called by GDI when the last active DirectDraw program
  263. * is quit and DirectDraw will no longer be active.
  264. *
  265. \**************************************************************************/
  266. VOID DrvDisableDirectDraw(
  267. DHPDEV dhpdev)
  268. {
  269. PDEV* ppdev;
  270. ppdev = (PDEV*) dhpdev;
  271. // DirectDraw is done with the display, so we can go back to using
  272. // all of off-screen memory ourselves:
  273. pohFree(ppdev, ppdev->pohDirectDraw);
  274. ppdev->pohDirectDraw = NULL;
  275. }
  276. /******************************Public*Routine******************************\
  277. * VOID vAssertModeDirectDraw
  278. *
  279. * This function is called by enable.c when entering or leaving the
  280. * DOS full-screen character mode.
  281. *
  282. \**************************************************************************/
  283. VOID vAssertModeDirectDraw(
  284. PDEV* ppdev,
  285. BOOL bEnabled)
  286. {
  287. }
  288. /******************************Public*Routine******************************\
  289. * BOOL bEnableDirectDraw
  290. *
  291. * This function is called by enable.c when the mode is first initialized,
  292. * right after the miniport does the mode-set.
  293. *
  294. \**************************************************************************/
  295. BOOL bEnableDirectDraw(
  296. PDEV* ppdev)
  297. {
  298. // if no APERATURE then we are a MACH8 and have no DDraw support
  299. if (ppdev->iAperture != APERTURE_NONE)
  300. {
  301. // Accurately measure the refresh rate for later:
  302. ppdev->bPassVBlank=TRUE;
  303. if (ppdev->iMachType == MACH_MM_32)
  304. {
  305. // Can do memory-mapped IO:
  306. vGetDisplayDuration32M(ppdev);
  307. }
  308. else if (ppdev->iMachType == MACH_IO_32 )
  309. {
  310. vGetDisplayDuration32I(ppdev);
  311. }
  312. else
  313. { // MACH 64
  314. // we have a problem with VBLANK on high speed multiprocessors machines on GX-F
  315. // so right now will test the VBlank routine; if OK report FLIP capabilities, otherwise no.
  316. int j;
  317. LONGLONG Counter[2], Freq;
  318. EngQueryPerformanceFrequency(&Freq);
  319. for (j = 0; j < 10; j++)
  320. {
  321. EngQueryPerformanceCounter(&Counter[0]);
  322. while (IN_VBLANK_64( ppdev->pjMmBase))
  323. {
  324. EngQueryPerformanceCounter(&Counter[1]);
  325. if( (ULONG)(Counter[1]-Counter[0]) >= (ULONG)Freq ) // if we are here more than 1 sec
  326. {
  327. // we are stuck inside the VBlank routine
  328. ppdev->bPassVBlank=FALSE;
  329. goto ExitVBlankTest;
  330. }
  331. }
  332. EngQueryPerformanceCounter(&Counter[0]);
  333. while (!(IN_VBLANK_64( ppdev->pjMmBase)))
  334. {
  335. EngQueryPerformanceCounter(&Counter[1]);
  336. if( (ULONG)(Counter[1]-Counter[0]) >= (ULONG)Freq) // if we are here more than 1 sec
  337. {
  338. // we are stuck inside the VBlank routine
  339. ppdev->bPassVBlank=FALSE;
  340. goto ExitVBlankTest;
  341. }
  342. }
  343. }
  344. ExitVBlankTest:
  345. vGetDisplayDuration64(ppdev);
  346. }
  347. }
  348. return(TRUE);
  349. }
  350. /******************************Public*Routine******************************\
  351. * VOID vDisableDirectDraw
  352. *
  353. * This function is called by enable.c when the driver is shutting down.
  354. *
  355. \**************************************************************************/
  356. VOID vDisableDirectDraw(
  357. PDEV* ppdev)
  358. {
  359. }