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.

841 lines
23 KiB

  1. /*========================================================================== *
  2. *
  3. * Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: ddalias.c
  6. * Content: DirectDraw support for allocating and mapping linear virtual
  7. * memory aliased for video memory.
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 05-jul-96 colinmc initial implementation
  12. * 10-oct-96 colinmc Refinements of the Win16 locking stuff
  13. * 12-oct-96 colinmc Improvements to Win16 locking code to reduce virtual
  14. * memory usage
  15. * 25-jan-97 colinmc AGP work
  16. * 01-jun-97 colinmc Bug xxxx: Defensive video memory checking to catch
  17. * based video memory pointers passed by drivers
  18. *
  19. ***************************************************************************/
  20. #include "ddrawpr.h"
  21. #ifdef USE_ALIAS
  22. #ifdef WINNT
  23. #include "ddrawgdi.h"
  24. #endif
  25. #pragma optimize("gle", off)
  26. #define Not_VxD
  27. #include <vmm.h>
  28. #include <configmg.h>
  29. #pragma optimize("", on)
  30. /*
  31. * We define the page lock IOCTLs here so that we don't have to include ddvxd.h.
  32. * These must match the corresponding entries in ddvxd.h
  33. */
  34. #define DDVXD_IOCTL_MEMRESERVEALIAS 23
  35. #define DDVXD_IOCTL_MEMCOMMITALIAS 24
  36. #define DDVXD_IOCTL_MEMREDIRECTALIAS 25
  37. #define DDVXD_IOCTL_MEMDECOMMITALIAS 26
  38. #define DDVXD_IOCTL_MEMFREEALIAS 27
  39. #define DDVXD_IOCTL_MEMCOMMITPHYSALIAS 55
  40. #define DDVXD_IOCTL_MEMREDIRECTPHYSALIAS 56
  41. #define DDVXD_IOCTL_LINTOPHYS 69
  42. #define GET_PIXELFORMAT( pdrv, psurf_lcl ) \
  43. ( ( ( psurf_lcl )->dwFlags & DDRAWISURF_HASPIXELFORMAT ) ? \
  44. &( ( psurf_lcl )->lpGbl->ddpfSurface ) : \
  45. &( ( pdrv )->vmiData.ddpfDisplay ) )
  46. #define WIDTH_TO_BYTES( bpp, w ) ( ( ( ( w ) * ( bpp ) ) + 7 ) >> 3 )
  47. BOOL UnmapHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo );
  48. /*
  49. * Are the heaps mapped at all?
  50. */
  51. #define HEAPALIASINFO_MAPPED ( HEAPALIASINFO_MAPPEDREAL | HEAPALIASINFO_MAPPEDDUMMY )
  52. #define MAP_HEAP_ALIAS_TO_VID_MEM( hvxd, lpHeapAlias ) \
  53. vxdMapVMAliasToVidMem( (hvxd), \
  54. (lpHeapAlias)->lpAlias, \
  55. (lpHeapAlias)->dwAliasSize, \
  56. (LPVOID)(lpHeapAlias)->fpVidMem )
  57. #define MAP_HEAP_ALIAS_TO_DUMMY_MEM( hvxd, lpHeapAlias ) \
  58. vxdMapVMAliasToDummyMem( (hvxd), \
  59. (lpHeapAlias)->lpAlias, \
  60. (lpHeapAlias)->dwAliasSize )
  61. #define UNMAP_HEAP_ALIAS( hvxd, lpHeapAlias ) \
  62. vxdUnmapVMAlias( (hvxd), \
  63. (lpHeapAlias)->lpAlias, \
  64. (lpHeapAlias)->dwAliasSize )
  65. #undef DPF_MODNAME
  66. #define DPF_MODNAME "vxdAllocVMAlias"
  67. /*
  68. * vxdAllocVMAlias
  69. *
  70. * Allocate a virtual memory alias for a portion of video memory
  71. * starting with the given start address and size.
  72. */
  73. static BOOL vxdAllocVMAlias( HANDLE hvxd, LPVOID lpVidMem, DWORD dwSize, LPVOID *lplpAlias )
  74. {
  75. LPVOID lpAlias;
  76. DWORD cbReturned;
  77. BOOL rc;
  78. struct RAInput
  79. {
  80. LPBYTE lpVidMem;
  81. DWORD dwSize;
  82. } raInput;
  83. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  84. DDASSERT( NULL != lpVidMem );
  85. DDASSERT( 0UL != dwSize );
  86. DDASSERT( NULL != lplpAlias );
  87. raInput.lpVidMem = (LPBYTE) lpVidMem;
  88. raInput.dwSize = dwSize;
  89. DPF( 5, "Trying to allocate alias starting at 0x%08x of size 0x%04x", lpVidMem, dwSize );
  90. rc = DeviceIoControl( hvxd,
  91. DDVXD_IOCTL_MEMRESERVEALIAS,
  92. &raInput,
  93. sizeof( raInput ),
  94. &lpAlias,
  95. sizeof( lpAlias ),
  96. &cbReturned,
  97. NULL);
  98. if( rc )
  99. {
  100. DDASSERT( cbReturned == sizeof(lpAlias) );
  101. *lplpAlias = lpAlias;
  102. }
  103. else
  104. {
  105. DPF( 0, "Could not allocate an alias for video memory starting at 0x%08x", lpVidMem );
  106. *lplpAlias = NULL;
  107. }
  108. return rc;
  109. } /* vxdAllocVMAlias */
  110. #undef DPF_MODNAME
  111. #define DPF_MODNAME "vxdFreeVMAlias"
  112. /*
  113. * vxdFreeVMAlias
  114. *
  115. * Free the virtual memory alias with the given start address and size.
  116. */
  117. static BOOL vxdFreeVMAlias( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize )
  118. {
  119. BOOL rc;
  120. BOOL fSuccess;
  121. DWORD cbReturned;
  122. struct FAInput
  123. {
  124. LPBYTE pAlias;
  125. DWORD cbBuffer;
  126. } faInput;
  127. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  128. DDASSERT( NULL != lpAlias);
  129. DDASSERT( 0UL != dwSize );
  130. faInput.pAlias = (LPBYTE) lpAlias;
  131. faInput.cbBuffer = dwSize;
  132. DPF( 5, "Trying to free an alias starting at 0x%08x of size 0x%04x", lpAlias, dwSize );
  133. rc = DeviceIoControl( hvxd,
  134. DDVXD_IOCTL_MEMFREEALIAS,
  135. &faInput,
  136. sizeof( faInput ),
  137. &fSuccess,
  138. sizeof( fSuccess ),
  139. &cbReturned,
  140. NULL);
  141. if( !rc || !fSuccess )
  142. {
  143. DPF( 0, "Could not free an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess );
  144. return FALSE;
  145. }
  146. return TRUE;
  147. } /* vxdFreeVMAlias */
  148. #undef DPF_MODNAME
  149. #define DPF_MODNAME "vxdMapVMAliasToVidMem"
  150. /*
  151. * vxdMapVMAliasToVidMem
  152. *
  153. * Map the the virtual memory alias with the given start address and size
  154. * to the porition of video memory with the given start address.
  155. */
  156. static BOOL vxdMapVMAliasToVidMem( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize, LPVOID lpVidMem )
  157. {
  158. BOOL rc;
  159. BOOL fSuccess;
  160. DWORD cbReturned;
  161. struct CAInput
  162. {
  163. LPBYTE pAlias;
  164. LPBYTE pVidMem;
  165. DWORD cbBuffer;
  166. } caInput;
  167. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  168. DDASSERT( NULL != lpAlias );
  169. DDASSERT( 0UL != dwSize );
  170. DDASSERT( NULL != lpVidMem );
  171. caInput.pAlias = (LPBYTE) lpAlias;
  172. caInput.pVidMem = (LPBYTE) lpVidMem;
  173. caInput.cbBuffer = dwSize;
  174. DPF( 5, "Trying to map an alias starting at 0x%08x of size 0x%04x to video memory starting at 0x%08x", lpAlias, dwSize, lpVidMem );
  175. rc = DeviceIoControl( hvxd,
  176. DDVXD_IOCTL_MEMCOMMITPHYSALIAS,
  177. &caInput,
  178. sizeof( caInput ),
  179. &fSuccess,
  180. sizeof( fSuccess ),
  181. &cbReturned,
  182. NULL);
  183. if( !rc || !fSuccess )
  184. {
  185. DPF( 0, "Could not map an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess );
  186. return FALSE;
  187. }
  188. return TRUE;
  189. } /* vxdMapVMAliasToVidMem */
  190. #undef DPF_MODNAME
  191. #define DPF_MODNAME "vxdMapVMAliasToDummyMem"
  192. /*
  193. * vxdMapVMAliasToDummyMem
  194. *
  195. * Map the the virtual memory alias with the given start address and size
  196. * to a read / write dummy page.
  197. */
  198. static BOOL vxdMapVMAliasToDummyMem( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize )
  199. {
  200. BOOL rc;
  201. BOOL fSuccess;
  202. DWORD cbReturned;
  203. struct RAInput
  204. {
  205. LPBYTE pAlias;
  206. DWORD cbBuffer;
  207. } raInput;
  208. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  209. DDASSERT( NULL != lpAlias);
  210. DDASSERT( 0UL != dwSize );
  211. raInput.pAlias = (LPBYTE) lpAlias;
  212. raInput.cbBuffer = dwSize;
  213. DPF( 5, "Trying to map an alias starting at 0x%08x of size 0x%04x to dummy memory" , lpAlias, dwSize );
  214. rc = DeviceIoControl( hvxd,
  215. DDVXD_IOCTL_MEMREDIRECTPHYSALIAS,
  216. &raInput,
  217. sizeof( raInput ),
  218. &fSuccess,
  219. sizeof( fSuccess ),
  220. &cbReturned,
  221. NULL);
  222. if( !rc || !fSuccess )
  223. {
  224. DPF( 0, "Could not map an alias starting at 0x%08x to dummy memory (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess );
  225. return FALSE;
  226. }
  227. return TRUE;
  228. } /* vxdMapVMAliasToDummyMem */
  229. #undef DPF_MODNAME
  230. #define DPF_MODNAME "vxdUnmapVMAlias"
  231. /*
  232. * vxdUnmapVMAlias
  233. *
  234. * Unmap the the virtual memory alias with the given start address and size.
  235. */
  236. static BOOL vxdUnmapVMAlias( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize )
  237. {
  238. BOOL rc;
  239. BOOL fSuccess;
  240. DWORD cbReturned;
  241. struct DAInput
  242. {
  243. LPBYTE pAlias;
  244. DWORD cbBuffer;
  245. } daInput;
  246. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  247. DDASSERT( NULL != lpAlias);
  248. DDASSERT( 0UL != dwSize );
  249. daInput.pAlias = (LPBYTE) lpAlias;
  250. daInput.cbBuffer = dwSize;
  251. DPF( 5, "Trying to unmap an alias starting at 0x%08x of size 0x%04x", lpAlias, dwSize );
  252. rc = DeviceIoControl( hvxd,
  253. DDVXD_IOCTL_MEMDECOMMITALIAS,
  254. &daInput,
  255. sizeof( daInput ),
  256. &fSuccess,
  257. sizeof( fSuccess ),
  258. &cbReturned,
  259. NULL );
  260. if( !rc || !fSuccess )
  261. {
  262. DPF( 0, "Could not unmap an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess );
  263. return FALSE;
  264. }
  265. return TRUE;
  266. } /* vxdUnmapVMAlias */
  267. static BOOL vxdLinToPhys( HANDLE hvxd, LPVOID lpLin, DWORD dwSize, LPVOID* lplpPhys )
  268. {
  269. BOOL rc;
  270. LPBYTE lpPhys;
  271. DWORD cbReturned;
  272. struct DAInput
  273. {
  274. LPBYTE pLin;
  275. DWORD cbBuffer;
  276. } daInput;
  277. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  278. DDASSERT( NULL != lpLin);
  279. // There really is a bug here: 27001. But since it's MOSTLY inoccuous, I'll turn the spew off.
  280. // DDASSERT( 0UL != dwSize );
  281. daInput.pLin = (LPBYTE) lpLin;
  282. daInput.cbBuffer = dwSize;
  283. DPF( 5, "Trying to map an linear address at 0x%08x of size 0x%04x to physical address", lpLin, dwSize );
  284. rc = DeviceIoControl( hvxd,
  285. DDVXD_IOCTL_LINTOPHYS,
  286. &daInput,
  287. sizeof( daInput ),
  288. &lpPhys,
  289. sizeof( lpPhys ),
  290. &cbReturned,
  291. NULL );
  292. if( rc )
  293. {
  294. DDASSERT( cbReturned == sizeof(lpPhys) );
  295. *lplpPhys = lpPhys;
  296. }
  297. else
  298. {
  299. DPF( 0, "Could not map linear address at 0x%08x to physical address", lpLin );
  300. *lplpPhys = NULL;
  301. }
  302. return rc;
  303. } /* vxdUnmapVMAlias */
  304. #undef DPF_MODNAME
  305. #define DPF_MODNAME "AllocHeapAlias"
  306. /*
  307. * AllocHeapAlias
  308. *
  309. * Allocate a virtual memory alias for the given heap
  310. */
  311. static BOOL AllocHeapAlias( HANDLE hvxd, FLATPTR fpStart, DWORD dwSize, LPHEAPALIAS lpHeapAlias )
  312. {
  313. LPVOID lpAlias;
  314. BOOL fSuccess;
  315. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  316. DDASSERT( 0UL != fpStart ); /* This is a physical address pointer */
  317. DDASSERT( 0UL != dwSize );
  318. DDASSERT( NULL != lpHeapAlias );
  319. /*
  320. * Attempt to allocate an alias for this heap.
  321. */
  322. fSuccess = vxdAllocVMAlias( hvxd, (LPVOID) fpStart, dwSize, &lpAlias );
  323. if( fSuccess )
  324. {
  325. lpHeapAlias->fpVidMem = fpStart;
  326. lpHeapAlias->lpAlias = lpAlias;
  327. lpHeapAlias->dwAliasSize = dwSize;
  328. }
  329. else
  330. {
  331. lpHeapAlias->fpVidMem = 0UL;
  332. lpHeapAlias->lpAlias = NULL;
  333. lpHeapAlias->dwAliasSize = 0UL;
  334. }
  335. return fSuccess;
  336. } /* AllocHeapAlias */
  337. #undef DPF_MODNAME
  338. #define DPF_MODNAME "FreeHeapAlias"
  339. /*
  340. * FreeHeapAlias
  341. *
  342. * Free the given virtual memory heap alias
  343. */
  344. static BOOL FreeHeapAlias( HANDLE hvxd, LPHEAPALIAS lpHeapAlias )
  345. {
  346. BOOL fSuccess;
  347. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  348. DDASSERT( NULL != lpHeapAlias );
  349. if( NULL != lpHeapAlias->lpAlias )
  350. {
  351. fSuccess = vxdFreeVMAlias( hvxd, lpHeapAlias->lpAlias, lpHeapAlias->dwAliasSize );
  352. lpHeapAlias->fpVidMem = 0UL;
  353. lpHeapAlias->lpAlias = NULL;
  354. lpHeapAlias->dwAliasSize = 0UL;
  355. }
  356. return fSuccess;
  357. } /* FreeHeapAliases */
  358. #undef DPF_MODNAME
  359. #define DPF_MODNAME "CreateHeapAliases"
  360. /*
  361. * CreateHeapAliases
  362. *
  363. * Create a new set of virtual memory heap aliases for the given global
  364. * object
  365. */
  366. HRESULT CreateHeapAliases( HANDLE hvxd, LPDDRAWI_DIRECTDRAW_GBL pdrv )
  367. {
  368. LPHEAPALIASINFO phaiInfo;
  369. DWORD dwNumHeaps;
  370. DWORD dwSize;
  371. DWORD dwHeapNo;
  372. int i;
  373. int n;
  374. HRESULT hres;
  375. CMCONFIG config;
  376. LPVIDMEM pvm;
  377. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  378. DDASSERT( NULL != pdrv );
  379. DDASSERT( NULL == pdrv->phaiHeapAliases );
  380. DDASSERT( !( pdrv->dwFlags & DDRAWI_NOHARDWARE ) );
  381. DDASSERT( !( pdrv->dwFlags & DDRAWI_MODEX ) );
  382. DDASSERT( 0UL != pdrv->vmiData.fpPrimary );
  383. if (DD16_GetDeviceConfig(pdrv->cDriverName, &config, sizeof(config)) == 0)
  384. {
  385. DPF_ERR("Could not get display devices's address space ranges");
  386. return DDERR_GENERIC;
  387. }
  388. // First we count the cards local vid mem windows in the config space
  389. dwNumHeaps = config.wNumMemWindows;
  390. DPF(5, "Config Space windows = %d", dwNumHeaps);
  391. // Then we cycle through the AGP heaps that we need to alias
  392. for( i = 0; i < (int)pdrv->vmiData.dwNumHeaps; i++ )
  393. {
  394. if( ( pdrv->vmiData.pvmList[i].dwFlags & VIDMEM_ISNONLOCAL ) )
  395. {
  396. // Found AGP heap
  397. ++dwNumHeaps;
  398. }
  399. }
  400. DPF(5, "dwNumHeaps = %d", dwNumHeaps);
  401. /*
  402. * Allocate the heap alias info.
  403. */
  404. phaiInfo = MemAlloc( sizeof( HEAPALIASINFO ) );
  405. if( NULL == phaiInfo )
  406. {
  407. DPF_ERR( "Insufficient memory to map the heap alias info" );
  408. return DDERR_OUTOFMEMORY;
  409. }
  410. /*
  411. * Heaps are not yet mapped.
  412. */
  413. phaiInfo->dwFlags &= ~HEAPALIASINFO_MAPPED;
  414. /*
  415. * Allocate the array of heap aliases.
  416. */
  417. phaiInfo->lpAliases = MemAlloc( dwNumHeaps * sizeof( HEAPALIAS ) );
  418. if( NULL == phaiInfo->lpAliases )
  419. {
  420. DPF_ERR( "Insufficient memory to allocate heap alias array" );
  421. MemFree( phaiInfo );
  422. return DDERR_OUTOFMEMORY;
  423. }
  424. phaiInfo->dwNumHeaps = dwNumHeaps;
  425. /*
  426. * Allocate the aliases for each vid mem config space window.
  427. */
  428. for( i = 0; i < (int) config.wNumMemWindows; i++ )
  429. {
  430. DPF(5, "Window %d: wMemAttrib = %d", i, config.wMemAttrib[i]);
  431. DPF(5, "Window %d: dMemBase = 0x%08x", i, config.dMemBase[i]);
  432. DPF(5, "Window %d: dMemLength = 0x%08x", i, config.dMemLength[i]);
  433. if ((config.wMemAttrib[i] & fMD_MemoryType) == fMD_ROM)
  434. {
  435. DPF(5, "fMD_MemoryType == fMD_ROM, skipping...");
  436. continue;
  437. }
  438. if( !AllocHeapAlias( hvxd, config.dMemBase[i], config.dMemLength[i], &phaiInfo->lpAliases[i] ) )
  439. {
  440. DPF_ERR( "Insufficient memory to allocate virtual memory alias" );
  441. /*
  442. * Discard any aliases already allocated.
  443. */
  444. for( n = 0; n < i; n++)
  445. FreeHeapAlias( hvxd, &phaiInfo->lpAliases[n] );
  446. MemFree( phaiInfo->lpAliases );
  447. MemFree( phaiInfo );
  448. return DDERR_OUTOFMEMORY;
  449. }
  450. }
  451. /*
  452. * Allocate the aliases for each AGP heap.
  453. */
  454. dwHeapNo = config.wNumMemWindows;
  455. for( i = 0; i < (int)pdrv->vmiData.dwNumHeaps; i++ )
  456. {
  457. pvm = &(pdrv->vmiData.pvmList[i]);
  458. if( ( pvm->dwFlags & VIDMEM_ISNONLOCAL ) )
  459. {
  460. DPF(5, "AGP Heap %d: fpGARTLin = 0x%08x", i, pvm->lpHeap->fpGARTLin);
  461. DPF(5, "AGP Heap %d: fpGARTDev = 0x%08x", i, pvm->lpHeap->fpGARTDev);
  462. DPF(5, "AGP Heap %d: dwTotalSize = 0x%08x", i, pvm->lpHeap->dwTotalSize);
  463. if( !AllocHeapAlias( hvxd, pvm->lpHeap->fpGARTDev, pvm->lpHeap->dwTotalSize, &phaiInfo->lpAliases[dwHeapNo] ) )
  464. {
  465. DPF_ERR( "Insufficient memory to allocate virtual memory alias" );
  466. /*
  467. * Discard any aliases already allocated.
  468. */
  469. for( n = 0; n < (int)dwHeapNo; n++)
  470. FreeHeapAlias( hvxd, &phaiInfo->lpAliases[n] );
  471. MemFree( phaiInfo->lpAliases );
  472. MemFree( phaiInfo );
  473. return DDERR_OUTOFMEMORY;
  474. }
  475. dwHeapNo++;
  476. }
  477. }
  478. /*
  479. * Now map all the aliases to video memory.
  480. */
  481. hres = MapHeapAliasesToVidMem( hvxd, phaiInfo );
  482. if( FAILED( hres ) )
  483. {
  484. for( i = 0; i < (int) dwNumHeaps; i++)
  485. FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] );
  486. MemFree( phaiInfo->lpAliases );
  487. MemFree( phaiInfo );
  488. return hres;
  489. }
  490. /*
  491. * The global object holds a single reference to the aliases
  492. */
  493. phaiInfo->dwRefCnt = 1UL;
  494. pdrv->phaiHeapAliases = phaiInfo;
  495. return DD_OK;
  496. } /* CreateHeapAliases */
  497. #undef DPF_MODNAME
  498. #define DPF_MODNAME "ReleaseHeapAliases"
  499. /*
  500. * ReleaseHeapAliases
  501. *
  502. * Release the given heap aliases.
  503. */
  504. BOOL ReleaseHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo )
  505. {
  506. int i;
  507. DDASSERT( NULL != phaiInfo );
  508. DDASSERT( 0UL != phaiInfo->dwRefCnt );
  509. phaiInfo->dwRefCnt--;
  510. if( 0UL == phaiInfo->dwRefCnt )
  511. {
  512. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  513. DPF( 4, "Heap aliases reference count is zero: discarding aliases" );
  514. /*
  515. * If the heaps are currently mapped then unmap them before
  516. * freeing them.
  517. */
  518. DDASSERT( phaiInfo->dwFlags & HEAPALIASINFO_MAPPED );
  519. UnmapHeapAliases( hvxd, phaiInfo );
  520. /*
  521. * Release all the virtual memory aliases.
  522. */
  523. for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ )
  524. {
  525. if( NULL != phaiInfo->lpAliases[i].lpAlias )
  526. FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] );
  527. }
  528. MemFree( phaiInfo->lpAliases );
  529. MemFree( phaiInfo );
  530. }
  531. return TRUE;
  532. } /* ReleaseHeapAliases */
  533. #undef DPF_MODNAME
  534. #define DPF_MODNAME "MapHeapAliasesToVidMem"
  535. /*
  536. * MapHeapAliasesToVidMem
  537. *
  538. * Map all the heap aliases to video memory.
  539. */
  540. HRESULT MapHeapAliasesToVidMem( HANDLE hvxd, LPHEAPALIASINFO phaiInfo )
  541. {
  542. int i;
  543. DDASSERT( NULL != phaiInfo );
  544. if( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDREAL )
  545. {
  546. DPF( 4, "Heap aliases already mapped to real video memory" );
  547. return DD_OK;
  548. }
  549. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  550. for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ )
  551. {
  552. /*
  553. * NOTE: If any of the maps fail then we just discard the
  554. * alias and continue. Memory allocated out of the failed
  555. * heap will need the Win16 lock taken.
  556. */
  557. if( NULL != phaiInfo->lpAliases[i].lpAlias )
  558. {
  559. if( !MAP_HEAP_ALIAS_TO_VID_MEM( hvxd, &phaiInfo->lpAliases[i] ) )
  560. {
  561. DPF( 0, "Heap %d failed to map. Discarding that alias", i );
  562. FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] );
  563. }
  564. }
  565. }
  566. phaiInfo->dwFlags = ((phaiInfo->dwFlags & ~HEAPALIASINFO_MAPPEDDUMMY) | HEAPALIASINFO_MAPPEDREAL);
  567. return DD_OK;
  568. } /* MapHeapAliasesToVidMem */
  569. #undef DPF_MODNAME
  570. #define DPF_MODNAME "MapHeapAliasesToDummyMem"
  571. /*
  572. * MapHeapAliasesToDummyMem
  573. *
  574. * Map all the heap aliases to the dummy read / write page.
  575. *
  576. * NOTE: The heap aliases must be mapped to real video memory before
  577. * calling this function.
  578. */
  579. HRESULT MapHeapAliasesToDummyMem( HANDLE hvxd, LPHEAPALIASINFO phaiInfo )
  580. {
  581. int i;
  582. HRESULT hres;
  583. DDASSERT( NULL != phaiInfo );
  584. if( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDDUMMY )
  585. {
  586. DPF( 4, "Heap aliases already mapped to dummy memory" );
  587. return DD_OK;
  588. }
  589. DDASSERT( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDREAL );
  590. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  591. hres = DD_OK;
  592. for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ )
  593. {
  594. if( NULL != phaiInfo->lpAliases[i].lpAlias )
  595. {
  596. if( !MAP_HEAP_ALIAS_TO_DUMMY_MEM( hvxd, &phaiInfo->lpAliases[i] ) )
  597. {
  598. /*
  599. * Keep going but flag the failure.
  600. */
  601. DPF( 0, "Could not map the heap alias to dummy memory" );
  602. hres = DDERR_GENERIC;
  603. }
  604. }
  605. }
  606. phaiInfo->dwFlags = ((phaiInfo->dwFlags & ~HEAPALIASINFO_MAPPEDREAL) | HEAPALIASINFO_MAPPEDDUMMY);
  607. return hres;
  608. } /* MapHeapAliasesToDummyMem */
  609. #undef DPF_MODNAME
  610. #define DPF_MODNAME "UnmapHeapAliases"
  611. /*
  612. * UnmapHeapAliases
  613. *
  614. * Unmap all the heap aliases.
  615. */
  616. BOOL UnmapHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo )
  617. {
  618. int i;
  619. DDASSERT( NULL != phaiInfo );
  620. if( 0UL == ( phaiInfo->dwFlags & HEAPALIASINFO_MAPPED ) )
  621. {
  622. DPF( 4, "Heap aliases already unmapped" );
  623. return TRUE;
  624. }
  625. DDASSERT( INVALID_HANDLE_VALUE != hvxd );
  626. for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ )
  627. {
  628. if( NULL != phaiInfo->lpAliases[i].lpAlias )
  629. {
  630. /*
  631. * Nothing we can do if the unmap fails.
  632. */
  633. UNMAP_HEAP_ALIAS( hvxd, &phaiInfo->lpAliases[i] );
  634. }
  635. }
  636. phaiInfo->dwFlags &= ~HEAPALIASINFO_MAPPED;
  637. return TRUE;
  638. } /* UnmapHeapAliases */
  639. /*
  640. * GetAliasedVidMem
  641. *
  642. * Get an alias for the given surface with the given video
  643. * memory pointer.
  644. */
  645. FLATPTR GetAliasedVidMem( LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl,
  646. LPDDRAWI_DDRAWSURFACE_LCL surf_lcl,
  647. FLATPTR fpVidMem )
  648. {
  649. LPDDRAWI_DDRAWSURFACE_GBL surf;
  650. LPDDRAWI_DIRECTDRAW_GBL pdrv;
  651. LPDDPIXELFORMAT lpddpf;
  652. DWORD dwVidMemSize;
  653. int n;
  654. LPHEAPALIAS phaAlias;
  655. DWORD dwHeapOffset;
  656. FLATPTR fpAliasedVidMem;
  657. FLATPTR fpPhysVidMem;
  658. BOOL fSuccess;
  659. DDASSERT( NULL != pdrv_lcl );
  660. DDASSERT( NULL != surf_lcl );
  661. DDASSERT( 0UL != fpVidMem );
  662. surf = surf_lcl->lpGbl;
  663. pdrv = pdrv_lcl->lpGbl;
  664. /*
  665. * If there are not heap aliases we can't really return one.
  666. */
  667. if( NULL == pdrv->phaiHeapAliases )
  668. {
  669. DPF( 3, "Driver has no heap aliases. Returning a NULL alias pointer" );
  670. return (FLATPTR)NULL;
  671. }
  672. /*
  673. * Compute the (inclusive) last byte in the surface. We need this
  674. * to ensure that a surface pointers lies exactly in an aliased
  675. * heap.
  676. */
  677. if (surf_lcl->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER)
  678. dwVidMemSize = surf->dwLinearSize;
  679. else
  680. {
  681. GET_PIXEL_FORMAT( surf_lcl, surf, lpddpf );
  682. dwVidMemSize = ( ( ( surf->wHeight - 1 ) * labs( surf->lPitch ) ) +
  683. WIDTH_TO_BYTES( lpddpf->dwRGBBitCount, surf->wWidth ) );
  684. }
  685. DPF(5, "dwVidMemSize = 0x%08x", dwVidMemSize);
  686. fpAliasedVidMem = 0UL;
  687. fSuccess = vxdLinToPhys((HANDLE) pdrv_lcl->hDDVxd, (LPVOID)fpVidMem, dwVidMemSize, (LPVOID*)&fpPhysVidMem);
  688. if (fSuccess && (fpPhysVidMem != 0))
  689. {
  690. phaAlias = &pdrv->phaiHeapAliases->lpAliases[0];
  691. n = (int) pdrv->phaiHeapAliases->dwNumHeaps;
  692. while( n-- )
  693. {
  694. DPF( 5, "Checking heap %d Heap start = 0x%08x Heap size = 0x%08x VidMem = 0x%08x",
  695. n, phaAlias->fpVidMem, phaAlias->dwAliasSize , fpPhysVidMem );
  696. if( ( NULL != phaAlias->lpAlias ) &&
  697. ( fpPhysVidMem >= phaAlias->fpVidMem ) &&
  698. ( fpPhysVidMem + dwVidMemSize <= ( phaAlias->fpVidMem + phaAlias->dwAliasSize ) ) )
  699. {
  700. /*
  701. * Compute the aliased pointer we are going to return.
  702. */
  703. dwHeapOffset = (DWORD) fpPhysVidMem - phaAlias->fpVidMem;
  704. fpAliasedVidMem = (FLATPTR) ( ( (LPBYTE) phaAlias->lpAlias ) + dwHeapOffset );
  705. DPF( 5, "Aliased pointer: 0x%08x - Offset: 0x%08x - Aliased heap: 0x%08x - VidMem heap: 0x%08x",
  706. fpAliasedVidMem, dwHeapOffset, phaAlias->lpAlias, phaAlias->fpVidMem );
  707. break;
  708. }
  709. phaAlias++;
  710. }
  711. }
  712. else
  713. DPF(4, "Could not find contiguous physical memory for linear mem pointer.");
  714. return fpAliasedVidMem;
  715. }
  716. #endif /* USE_ALIAS */