|
|
/*========================================================================== *
* * Copyright (C) 1994-1995 Microsoft Corporation. All Rights Reserved. * * File: ddalias.c * Content: DirectDraw support for allocating and mapping linear virtual * memory aliased for video memory. * History: * Date By Reason * ==== == ====== * 05-jul-96 colinmc initial implementation * 10-oct-96 colinmc Refinements of the Win16 locking stuff * 12-oct-96 colinmc Improvements to Win16 locking code to reduce virtual * memory usage * 25-jan-97 colinmc AGP work * 01-jun-97 colinmc Bug xxxx: Defensive video memory checking to catch * based video memory pointers passed by drivers * ***************************************************************************/
#include "ddrawpr.h"
#ifdef USE_ALIAS
#ifdef WINNT
#include "ddrawgdi.h"
#endif
#pragma optimize("gle", off)
#define Not_VxD
#include <vmm.h>
#include <configmg.h>
#pragma optimize("", on)
/*
* We define the page lock IOCTLs here so that we don't have to include ddvxd.h. * These must match the corresponding entries in ddvxd.h */ #define DDVXD_IOCTL_MEMRESERVEALIAS 23
#define DDVXD_IOCTL_MEMCOMMITALIAS 24
#define DDVXD_IOCTL_MEMREDIRECTALIAS 25
#define DDVXD_IOCTL_MEMDECOMMITALIAS 26
#define DDVXD_IOCTL_MEMFREEALIAS 27
#define DDVXD_IOCTL_MEMCOMMITPHYSALIAS 55
#define DDVXD_IOCTL_MEMREDIRECTPHYSALIAS 56
#define DDVXD_IOCTL_LINTOPHYS 69
#define GET_PIXELFORMAT( pdrv, psurf_lcl ) \
( ( ( psurf_lcl )->dwFlags & DDRAWISURF_HASPIXELFORMAT ) ? \ &( ( psurf_lcl )->lpGbl->ddpfSurface ) : \ &( ( pdrv )->vmiData.ddpfDisplay ) )
#define WIDTH_TO_BYTES( bpp, w ) ( ( ( ( w ) * ( bpp ) ) + 7 ) >> 3 )
BOOL UnmapHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo );
/*
* Are the heaps mapped at all? */ #define HEAPALIASINFO_MAPPED ( HEAPALIASINFO_MAPPEDREAL | HEAPALIASINFO_MAPPEDDUMMY )
#define MAP_HEAP_ALIAS_TO_VID_MEM( hvxd, lpHeapAlias ) \
vxdMapVMAliasToVidMem( (hvxd), \ (lpHeapAlias)->lpAlias, \ (lpHeapAlias)->dwAliasSize, \ (LPVOID)(lpHeapAlias)->fpVidMem )
#define MAP_HEAP_ALIAS_TO_DUMMY_MEM( hvxd, lpHeapAlias ) \
vxdMapVMAliasToDummyMem( (hvxd), \ (lpHeapAlias)->lpAlias, \ (lpHeapAlias)->dwAliasSize )
#define UNMAP_HEAP_ALIAS( hvxd, lpHeapAlias ) \
vxdUnmapVMAlias( (hvxd), \ (lpHeapAlias)->lpAlias, \ (lpHeapAlias)->dwAliasSize )
#undef DPF_MODNAME
#define DPF_MODNAME "vxdAllocVMAlias"
/*
* vxdAllocVMAlias * * Allocate a virtual memory alias for a portion of video memory * starting with the given start address and size. */ static BOOL vxdAllocVMAlias( HANDLE hvxd, LPVOID lpVidMem, DWORD dwSize, LPVOID *lplpAlias ) { LPVOID lpAlias; DWORD cbReturned; BOOL rc; struct RAInput { LPBYTE lpVidMem; DWORD dwSize; } raInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( NULL != lpVidMem ); DDASSERT( 0UL != dwSize ); DDASSERT( NULL != lplpAlias );
raInput.lpVidMem = (LPBYTE) lpVidMem; raInput.dwSize = dwSize;
DPF( 5, "Trying to allocate alias starting at 0x%08x of size 0x%04x", lpVidMem, dwSize );
rc = DeviceIoControl( hvxd, DDVXD_IOCTL_MEMRESERVEALIAS, &raInput, sizeof( raInput ), &lpAlias, sizeof( lpAlias ), &cbReturned, NULL);
if( rc ) { DDASSERT( cbReturned == sizeof(lpAlias) );
*lplpAlias = lpAlias; } else { DPF( 0, "Could not allocate an alias for video memory starting at 0x%08x", lpVidMem );
*lplpAlias = NULL; }
return rc; } /* vxdAllocVMAlias */
#undef DPF_MODNAME
#define DPF_MODNAME "vxdFreeVMAlias"
/*
* vxdFreeVMAlias * * Free the virtual memory alias with the given start address and size. */ static BOOL vxdFreeVMAlias( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize ) { BOOL rc; BOOL fSuccess; DWORD cbReturned; struct FAInput { LPBYTE pAlias; DWORD cbBuffer; } faInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( NULL != lpAlias); DDASSERT( 0UL != dwSize );
faInput.pAlias = (LPBYTE) lpAlias; faInput.cbBuffer = dwSize;
DPF( 5, "Trying to free an alias starting at 0x%08x of size 0x%04x", lpAlias, dwSize );
rc = DeviceIoControl( hvxd, DDVXD_IOCTL_MEMFREEALIAS, &faInput, sizeof( faInput ), &fSuccess, sizeof( fSuccess ), &cbReturned, NULL);
if( !rc || !fSuccess ) { DPF( 0, "Could not free an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess ); return FALSE; }
return TRUE; } /* vxdFreeVMAlias */
#undef DPF_MODNAME
#define DPF_MODNAME "vxdMapVMAliasToVidMem"
/*
* vxdMapVMAliasToVidMem * * Map the the virtual memory alias with the given start address and size * to the porition of video memory with the given start address. */ static BOOL vxdMapVMAliasToVidMem( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize, LPVOID lpVidMem ) { BOOL rc; BOOL fSuccess; DWORD cbReturned; struct CAInput { LPBYTE pAlias; LPBYTE pVidMem; DWORD cbBuffer; } caInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( NULL != lpAlias ); DDASSERT( 0UL != dwSize ); DDASSERT( NULL != lpVidMem );
caInput.pAlias = (LPBYTE) lpAlias; caInput.pVidMem = (LPBYTE) lpVidMem; caInput.cbBuffer = dwSize;
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 );
rc = DeviceIoControl( hvxd, DDVXD_IOCTL_MEMCOMMITPHYSALIAS, &caInput, sizeof( caInput ), &fSuccess, sizeof( fSuccess ), &cbReturned, NULL);
if( !rc || !fSuccess ) { DPF( 0, "Could not map an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess ); return FALSE; }
return TRUE; } /* vxdMapVMAliasToVidMem */
#undef DPF_MODNAME
#define DPF_MODNAME "vxdMapVMAliasToDummyMem"
/*
* vxdMapVMAliasToDummyMem * * Map the the virtual memory alias with the given start address and size * to a read / write dummy page. */ static BOOL vxdMapVMAliasToDummyMem( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize ) { BOOL rc; BOOL fSuccess; DWORD cbReturned; struct RAInput { LPBYTE pAlias; DWORD cbBuffer; } raInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( NULL != lpAlias); DDASSERT( 0UL != dwSize );
raInput.pAlias = (LPBYTE) lpAlias; raInput.cbBuffer = dwSize;
DPF( 5, "Trying to map an alias starting at 0x%08x of size 0x%04x to dummy memory" , lpAlias, dwSize );
rc = DeviceIoControl( hvxd, DDVXD_IOCTL_MEMREDIRECTPHYSALIAS, &raInput, sizeof( raInput ), &fSuccess, sizeof( fSuccess ), &cbReturned, NULL);
if( !rc || !fSuccess ) { DPF( 0, "Could not map an alias starting at 0x%08x to dummy memory (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess ); return FALSE; }
return TRUE; } /* vxdMapVMAliasToDummyMem */
#undef DPF_MODNAME
#define DPF_MODNAME "vxdUnmapVMAlias"
/*
* vxdUnmapVMAlias * * Unmap the the virtual memory alias with the given start address and size. */ static BOOL vxdUnmapVMAlias( HANDLE hvxd, LPVOID lpAlias, DWORD dwSize ) { BOOL rc; BOOL fSuccess; DWORD cbReturned; struct DAInput { LPBYTE pAlias; DWORD cbBuffer; } daInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( NULL != lpAlias); DDASSERT( 0UL != dwSize );
daInput.pAlias = (LPBYTE) lpAlias; daInput.cbBuffer = dwSize;
DPF( 5, "Trying to unmap an alias starting at 0x%08x of size 0x%04x", lpAlias, dwSize );
rc = DeviceIoControl( hvxd, DDVXD_IOCTL_MEMDECOMMITALIAS, &daInput, sizeof( daInput ), &fSuccess, sizeof( fSuccess ), &cbReturned, NULL );
if( !rc || !fSuccess ) { DPF( 0, "Could not unmap an alias starting at 0x%08x (rc = %d fSuccess = %d)", lpAlias, rc, fSuccess ); return FALSE; }
return TRUE; } /* vxdUnmapVMAlias */
static BOOL vxdLinToPhys( HANDLE hvxd, LPVOID lpLin, DWORD dwSize, LPVOID* lplpPhys ) { BOOL rc; LPBYTE lpPhys; DWORD cbReturned; struct DAInput { LPBYTE pLin; DWORD cbBuffer; } daInput;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( NULL != lpLin); // There really is a bug here: 27001. But since it's MOSTLY inoccuous, I'll turn the spew off.
// DDASSERT( 0UL != dwSize );
daInput.pLin = (LPBYTE) lpLin; daInput.cbBuffer = dwSize;
DPF( 5, "Trying to map an linear address at 0x%08x of size 0x%04x to physical address", lpLin, dwSize );
rc = DeviceIoControl( hvxd, DDVXD_IOCTL_LINTOPHYS, &daInput, sizeof( daInput ), &lpPhys, sizeof( lpPhys ), &cbReturned, NULL );
if( rc ) { DDASSERT( cbReturned == sizeof(lpPhys) );
*lplpPhys = lpPhys; } else { DPF( 0, "Could not map linear address at 0x%08x to physical address", lpLin );
*lplpPhys = NULL; }
return rc; } /* vxdUnmapVMAlias */
#undef DPF_MODNAME
#define DPF_MODNAME "AllocHeapAlias"
/*
* AllocHeapAlias * * Allocate a virtual memory alias for the given heap */ static BOOL AllocHeapAlias( HANDLE hvxd, FLATPTR fpStart, DWORD dwSize, LPHEAPALIAS lpHeapAlias ) { LPVOID lpAlias; BOOL fSuccess;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( 0UL != fpStart ); /* This is a physical address pointer */ DDASSERT( 0UL != dwSize ); DDASSERT( NULL != lpHeapAlias );
/*
* Attempt to allocate an alias for this heap. */ fSuccess = vxdAllocVMAlias( hvxd, (LPVOID) fpStart, dwSize, &lpAlias ); if( fSuccess ) { lpHeapAlias->fpVidMem = fpStart; lpHeapAlias->lpAlias = lpAlias; lpHeapAlias->dwAliasSize = dwSize; } else { lpHeapAlias->fpVidMem = 0UL; lpHeapAlias->lpAlias = NULL; lpHeapAlias->dwAliasSize = 0UL; }
return fSuccess; } /* AllocHeapAlias */
#undef DPF_MODNAME
#define DPF_MODNAME "FreeHeapAlias"
/*
* FreeHeapAlias * * Free the given virtual memory heap alias */ static BOOL FreeHeapAlias( HANDLE hvxd, LPHEAPALIAS lpHeapAlias ) { BOOL fSuccess;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( NULL != lpHeapAlias );
if( NULL != lpHeapAlias->lpAlias ) { fSuccess = vxdFreeVMAlias( hvxd, lpHeapAlias->lpAlias, lpHeapAlias->dwAliasSize ); lpHeapAlias->fpVidMem = 0UL; lpHeapAlias->lpAlias = NULL; lpHeapAlias->dwAliasSize = 0UL; }
return fSuccess; } /* FreeHeapAliases */
#undef DPF_MODNAME
#define DPF_MODNAME "CreateHeapAliases"
/*
* CreateHeapAliases * * Create a new set of virtual memory heap aliases for the given global * object */ HRESULT CreateHeapAliases( HANDLE hvxd, LPDDRAWI_DIRECTDRAW_GBL pdrv ) { LPHEAPALIASINFO phaiInfo; DWORD dwNumHeaps; DWORD dwSize; DWORD dwHeapNo; int i; int n; HRESULT hres; CMCONFIG config; LPVIDMEM pvm;
DDASSERT( INVALID_HANDLE_VALUE != hvxd ); DDASSERT( NULL != pdrv ); DDASSERT( NULL == pdrv->phaiHeapAliases );
DDASSERT( !( pdrv->dwFlags & DDRAWI_NOHARDWARE ) ); DDASSERT( !( pdrv->dwFlags & DDRAWI_MODEX ) ); DDASSERT( 0UL != pdrv->vmiData.fpPrimary );
if (DD16_GetDeviceConfig(pdrv->cDriverName, &config, sizeof(config)) == 0) { DPF_ERR("Could not get display devices's address space ranges"); return DDERR_GENERIC; } // First we count the cards local vid mem windows in the config space
dwNumHeaps = config.wNumMemWindows; DPF(5, "Config Space windows = %d", dwNumHeaps); // Then we cycle through the AGP heaps that we need to alias
for( i = 0; i < (int)pdrv->vmiData.dwNumHeaps; i++ ) { if( ( pdrv->vmiData.pvmList[i].dwFlags & VIDMEM_ISNONLOCAL ) ) { // Found AGP heap
++dwNumHeaps; } } DPF(5, "dwNumHeaps = %d", dwNumHeaps);
/*
* Allocate the heap alias info. */ phaiInfo = MemAlloc( sizeof( HEAPALIASINFO ) ); if( NULL == phaiInfo ) { DPF_ERR( "Insufficient memory to map the heap alias info" ); return DDERR_OUTOFMEMORY; }
/*
* Heaps are not yet mapped. */ phaiInfo->dwFlags &= ~HEAPALIASINFO_MAPPED;
/*
* Allocate the array of heap aliases. */ phaiInfo->lpAliases = MemAlloc( dwNumHeaps * sizeof( HEAPALIAS ) ); if( NULL == phaiInfo->lpAliases ) { DPF_ERR( "Insufficient memory to allocate heap alias array" ); MemFree( phaiInfo ); return DDERR_OUTOFMEMORY; } phaiInfo->dwNumHeaps = dwNumHeaps;
/*
* Allocate the aliases for each vid mem config space window. */ for( i = 0; i < (int) config.wNumMemWindows; i++ ) { DPF(5, "Window %d: wMemAttrib = %d", i, config.wMemAttrib[i]); DPF(5, "Window %d: dMemBase = 0x%08x", i, config.dMemBase[i]); DPF(5, "Window %d: dMemLength = 0x%08x", i, config.dMemLength[i]); if ((config.wMemAttrib[i] & fMD_MemoryType) == fMD_ROM) { DPF(5, "fMD_MemoryType == fMD_ROM, skipping..."); continue; } if( !AllocHeapAlias( hvxd, config.dMemBase[i], config.dMemLength[i], &phaiInfo->lpAliases[i] ) ) { DPF_ERR( "Insufficient memory to allocate virtual memory alias" ); /*
* Discard any aliases already allocated. */ for( n = 0; n < i; n++) FreeHeapAlias( hvxd, &phaiInfo->lpAliases[n] ); MemFree( phaiInfo->lpAliases ); MemFree( phaiInfo ); return DDERR_OUTOFMEMORY; } }
/*
* Allocate the aliases for each AGP heap. */ dwHeapNo = config.wNumMemWindows; for( i = 0; i < (int)pdrv->vmiData.dwNumHeaps; i++ ) { pvm = &(pdrv->vmiData.pvmList[i]); if( ( pvm->dwFlags & VIDMEM_ISNONLOCAL ) ) { DPF(5, "AGP Heap %d: fpGARTLin = 0x%08x", i, pvm->lpHeap->fpGARTLin); DPF(5, "AGP Heap %d: fpGARTDev = 0x%08x", i, pvm->lpHeap->fpGARTDev); DPF(5, "AGP Heap %d: dwTotalSize = 0x%08x", i, pvm->lpHeap->dwTotalSize); if( !AllocHeapAlias( hvxd, pvm->lpHeap->fpGARTDev, pvm->lpHeap->dwTotalSize, &phaiInfo->lpAliases[dwHeapNo] ) ) { DPF_ERR( "Insufficient memory to allocate virtual memory alias" ); /*
* Discard any aliases already allocated. */ for( n = 0; n < (int)dwHeapNo; n++) FreeHeapAlias( hvxd, &phaiInfo->lpAliases[n] ); MemFree( phaiInfo->lpAliases ); MemFree( phaiInfo ); return DDERR_OUTOFMEMORY; } dwHeapNo++; } }
/*
* Now map all the aliases to video memory. */ hres = MapHeapAliasesToVidMem( hvxd, phaiInfo ); if( FAILED( hres ) ) { for( i = 0; i < (int) dwNumHeaps; i++) FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] ); MemFree( phaiInfo->lpAliases ); MemFree( phaiInfo ); return hres; }
/*
* The global object holds a single reference to the aliases */ phaiInfo->dwRefCnt = 1UL; pdrv->phaiHeapAliases = phaiInfo;
return DD_OK; } /* CreateHeapAliases */
#undef DPF_MODNAME
#define DPF_MODNAME "ReleaseHeapAliases"
/*
* ReleaseHeapAliases * * Release the given heap aliases. */ BOOL ReleaseHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo ) { int i;
DDASSERT( NULL != phaiInfo ); DDASSERT( 0UL != phaiInfo->dwRefCnt );
phaiInfo->dwRefCnt--; if( 0UL == phaiInfo->dwRefCnt ) { DDASSERT( INVALID_HANDLE_VALUE != hvxd );
DPF( 4, "Heap aliases reference count is zero: discarding aliases" );
/*
* If the heaps are currently mapped then unmap them before * freeing them. */ DDASSERT( phaiInfo->dwFlags & HEAPALIASINFO_MAPPED ); UnmapHeapAliases( hvxd, phaiInfo );
/*
* Release all the virtual memory aliases. */ for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ ) { if( NULL != phaiInfo->lpAliases[i].lpAlias ) FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] ); }
MemFree( phaiInfo->lpAliases ); MemFree( phaiInfo ); }
return TRUE; } /* ReleaseHeapAliases */
#undef DPF_MODNAME
#define DPF_MODNAME "MapHeapAliasesToVidMem"
/*
* MapHeapAliasesToVidMem * * Map all the heap aliases to video memory. */ HRESULT MapHeapAliasesToVidMem( HANDLE hvxd, LPHEAPALIASINFO phaiInfo ) { int i;
DDASSERT( NULL != phaiInfo );
if( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDREAL ) { DPF( 4, "Heap aliases already mapped to real video memory" ); return DD_OK; }
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ ) { /*
* NOTE: If any of the maps fail then we just discard the * alias and continue. Memory allocated out of the failed * heap will need the Win16 lock taken. */ if( NULL != phaiInfo->lpAliases[i].lpAlias ) { if( !MAP_HEAP_ALIAS_TO_VID_MEM( hvxd, &phaiInfo->lpAliases[i] ) ) { DPF( 0, "Heap %d failed to map. Discarding that alias", i ); FreeHeapAlias( hvxd, &phaiInfo->lpAliases[i] ); } } }
phaiInfo->dwFlags = ((phaiInfo->dwFlags & ~HEAPALIASINFO_MAPPEDDUMMY) | HEAPALIASINFO_MAPPEDREAL);
return DD_OK; } /* MapHeapAliasesToVidMem */
#undef DPF_MODNAME
#define DPF_MODNAME "MapHeapAliasesToDummyMem"
/*
* MapHeapAliasesToDummyMem * * Map all the heap aliases to the dummy read / write page. * * NOTE: The heap aliases must be mapped to real video memory before * calling this function. */ HRESULT MapHeapAliasesToDummyMem( HANDLE hvxd, LPHEAPALIASINFO phaiInfo ) { int i; HRESULT hres;
DDASSERT( NULL != phaiInfo );
if( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDDUMMY ) { DPF( 4, "Heap aliases already mapped to dummy memory" ); return DD_OK; }
DDASSERT( phaiInfo->dwFlags & HEAPALIASINFO_MAPPEDREAL ); DDASSERT( INVALID_HANDLE_VALUE != hvxd );
hres = DD_OK; for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ ) { if( NULL != phaiInfo->lpAliases[i].lpAlias ) { if( !MAP_HEAP_ALIAS_TO_DUMMY_MEM( hvxd, &phaiInfo->lpAliases[i] ) ) { /*
* Keep going but flag the failure. */ DPF( 0, "Could not map the heap alias to dummy memory" ); hres = DDERR_GENERIC; } } }
phaiInfo->dwFlags = ((phaiInfo->dwFlags & ~HEAPALIASINFO_MAPPEDREAL) | HEAPALIASINFO_MAPPEDDUMMY);
return hres; } /* MapHeapAliasesToDummyMem */
#undef DPF_MODNAME
#define DPF_MODNAME "UnmapHeapAliases"
/*
* UnmapHeapAliases * * Unmap all the heap aliases. */ BOOL UnmapHeapAliases( HANDLE hvxd, LPHEAPALIASINFO phaiInfo ) { int i;
DDASSERT( NULL != phaiInfo );
if( 0UL == ( phaiInfo->dwFlags & HEAPALIASINFO_MAPPED ) ) { DPF( 4, "Heap aliases already unmapped" ); return TRUE; }
DDASSERT( INVALID_HANDLE_VALUE != hvxd );
for( i = 0; i < (int) phaiInfo->dwNumHeaps; i++ ) { if( NULL != phaiInfo->lpAliases[i].lpAlias ) { /*
* Nothing we can do if the unmap fails. */ UNMAP_HEAP_ALIAS( hvxd, &phaiInfo->lpAliases[i] ); } }
phaiInfo->dwFlags &= ~HEAPALIASINFO_MAPPED;
return TRUE; } /* UnmapHeapAliases */
/*
* GetAliasedVidMem * * Get an alias for the given surface with the given video * memory pointer. */ FLATPTR GetAliasedVidMem( LPDDRAWI_DIRECTDRAW_LCL pdrv_lcl, LPDDRAWI_DDRAWSURFACE_LCL surf_lcl, FLATPTR fpVidMem ) { LPDDRAWI_DDRAWSURFACE_GBL surf; LPDDRAWI_DIRECTDRAW_GBL pdrv; LPDDPIXELFORMAT lpddpf; DWORD dwVidMemSize; int n; LPHEAPALIAS phaAlias; DWORD dwHeapOffset; FLATPTR fpAliasedVidMem; FLATPTR fpPhysVidMem; BOOL fSuccess;
DDASSERT( NULL != pdrv_lcl ); DDASSERT( NULL != surf_lcl ); DDASSERT( 0UL != fpVidMem );
surf = surf_lcl->lpGbl; pdrv = pdrv_lcl->lpGbl;
/*
* If there are not heap aliases we can't really return one. */ if( NULL == pdrv->phaiHeapAliases ) { DPF( 3, "Driver has no heap aliases. Returning a NULL alias pointer" ); return (FLATPTR)NULL; }
/*
* Compute the (inclusive) last byte in the surface. We need this * to ensure that a surface pointers lies exactly in an aliased * heap. */ if (surf_lcl->ddsCaps.dwCaps & DDSCAPS_EXECUTEBUFFER) dwVidMemSize = surf->dwLinearSize; else { GET_PIXEL_FORMAT( surf_lcl, surf, lpddpf ); dwVidMemSize = ( ( ( surf->wHeight - 1 ) * labs( surf->lPitch ) ) + WIDTH_TO_BYTES( lpddpf->dwRGBBitCount, surf->wWidth ) ); } DPF(5, "dwVidMemSize = 0x%08x", dwVidMemSize); fpAliasedVidMem = 0UL; fSuccess = vxdLinToPhys((HANDLE) pdrv_lcl->hDDVxd, (LPVOID)fpVidMem, dwVidMemSize, (LPVOID*)&fpPhysVidMem); if (fSuccess && (fpPhysVidMem != 0)) { phaAlias = &pdrv->phaiHeapAliases->lpAliases[0]; n = (int) pdrv->phaiHeapAliases->dwNumHeaps; while( n-- ) { DPF( 5, "Checking heap %d Heap start = 0x%08x Heap size = 0x%08x VidMem = 0x%08x", n, phaAlias->fpVidMem, phaAlias->dwAliasSize , fpPhysVidMem );
if( ( NULL != phaAlias->lpAlias ) && ( fpPhysVidMem >= phaAlias->fpVidMem ) && ( fpPhysVidMem + dwVidMemSize <= ( phaAlias->fpVidMem + phaAlias->dwAliasSize ) ) ) { /*
* Compute the aliased pointer we are going to return. */ dwHeapOffset = (DWORD) fpPhysVidMem - phaAlias->fpVidMem; fpAliasedVidMem = (FLATPTR) ( ( (LPBYTE) phaAlias->lpAlias ) + dwHeapOffset );
DPF( 5, "Aliased pointer: 0x%08x - Offset: 0x%08x - Aliased heap: 0x%08x - VidMem heap: 0x%08x", fpAliasedVidMem, dwHeapOffset, phaAlias->lpAlias, phaAlias->fpVidMem ); break; } phaAlias++; } } else DPF(4, "Could not find contiguous physical memory for linear mem pointer."); return fpAliasedVidMem; }
#endif /* USE_ALIAS */
|