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
856 lines
29 KiB
/******************************Module*Header**********************************\
|
|
*
|
|
* **************************
|
|
* * DirectDraw SAMPLE CODE *
|
|
* **************************
|
|
*
|
|
* Module Name: ddenable.c
|
|
*
|
|
* Content: Windows 2000 only DirectDraw/D3D enabling functions
|
|
*
|
|
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
|
|
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
|
|
\*****************************************************************************/
|
|
#include "glint.h"
|
|
|
|
#if WNT_DDRAW
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// __DDE_BuildPixelFormat
|
|
//
|
|
// generate a pixel format structure based on the mode
|
|
// This example works only with RGB surfaces
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void
|
|
__DDE_BuildPixelFormat(
|
|
P3_THUNKEDDATA* pThisDisplay,
|
|
LPGLINTINFO pGLInfo,
|
|
LPDDPIXELFORMAT pdpf )
|
|
{
|
|
PPDEV ppdev;
|
|
|
|
ppdev = pThisDisplay->ppdev;
|
|
|
|
pdpf->dwSize = sizeof( DDPIXELFORMAT );
|
|
pdpf->dwFourCC = 0;
|
|
|
|
pdpf->dwFlags = DDPF_RGB;
|
|
|
|
if( pGLInfo->dwBpp == 8 )
|
|
{
|
|
pdpf->dwFlags |= DDPF_PALETTEINDEXED8;
|
|
}
|
|
pdpf->dwRGBBitCount = pGLInfo->dwBpp;
|
|
|
|
pdpf->dwRBitMask = ppdev->flRed;
|
|
pdpf->dwGBitMask = ppdev->flGreen;
|
|
pdpf->dwBBitMask = ppdev->flBlue;
|
|
|
|
// Calculate the alpha channel as it isn't in the ppdev
|
|
switch (pGLInfo->dwBpp)
|
|
{
|
|
case 8:
|
|
DISPDBG((DBGLVL, "Format is 8 bits"));
|
|
pdpf->dwRGBAlphaBitMask = 0;
|
|
break;
|
|
|
|
case 16:
|
|
DISPDBG((DBGLVL, "Format is 16 bits"));
|
|
switch(ppdev->flRed)
|
|
{
|
|
case 0x7C00:
|
|
pdpf->dwRGBAlphaBitMask = 0x8000L;
|
|
pdpf->dwFlags |= DDPF_ALPHAPIXELS;
|
|
break;
|
|
default:
|
|
pdpf->dwRGBAlphaBitMask = 0x0L;
|
|
}
|
|
break;
|
|
case 24:
|
|
DISPDBG((DBGLVL, "Format is 24 bits"));
|
|
pdpf->dwRGBAlphaBitMask = 0x00000000L;
|
|
break;
|
|
case 32:
|
|
DISPDBG((DBGLVL, "Desktop is 32 bits"));
|
|
pdpf->dwRGBAlphaBitMask = 0xff000000L;
|
|
pdpf->dwFlags |= DDPF_ALPHAPIXELS;
|
|
break;
|
|
|
|
}
|
|
} // __DDE_BuildPixelFormat
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// __DDE_bSetupDDStructs
|
|
//
|
|
// This fills in the data that would have been setup on Win9X in the
|
|
// 16 bit side
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL
|
|
__DDE_bSetupDDStructs(
|
|
P3_THUNKEDDATA* pThisDisplay,
|
|
BOOL reset )
|
|
{
|
|
DWORD dwRegistryValue;
|
|
BOOL bSuccess;
|
|
LPGLINTINFO pGLInfo;
|
|
PPDEV ppdev;
|
|
void *fbPtr; // Framebuffer pointer
|
|
void *lbPtr; // Localbuffer pointer
|
|
DWORD fbSizeInBytes; // Size of framebuffer
|
|
DWORD lbSizeInBytes; // Size of localbuffer
|
|
DWORD fbOffsetInBytes; // Offset to 1st 'free' byte in framebuffer
|
|
DWORD dwMemStart, dwMemEnd;
|
|
|
|
// reset == TRUE if there has been a mode change.
|
|
pThisDisplay->bResetMode = reset;
|
|
|
|
#if DBG
|
|
if (pThisDisplay->bResetMode)
|
|
{
|
|
DISPDBG((DBGLVL,"Resetting due to mode change"));
|
|
}
|
|
else
|
|
{
|
|
DISPDBG((DBGLVL, "Creating for the first time"));
|
|
}
|
|
#endif
|
|
|
|
// Setup pThisDisplay->pGLInfo from PPDEV
|
|
pGLInfo = pThisDisplay->pGLInfo;
|
|
ppdev = pThisDisplay->ppdev;
|
|
|
|
GetFBLBInfoForDDraw (ppdev,
|
|
&fbPtr, // Framebuffer pointer
|
|
&lbPtr, // Localbuffer pointer,
|
|
// (*** This is NULL***)
|
|
&fbSizeInBytes, // Size of framebuffer
|
|
&lbSizeInBytes, // Size of localbuffer
|
|
&fbOffsetInBytes, // Offset to 1st 'free' byte
|
|
// in framebuffer
|
|
&pGLInfo->bDRAMBoard);// TRUE if SDRAM vidmem,
|
|
// FALSE if SGRAM
|
|
// (i.e. hw writemask) vidmem
|
|
|
|
|
|
DISPDBG((DBGLVL, "__DDE_bSetupDDStructs: fbPtr 0x%lx, fbOff 0x%x",
|
|
fbPtr, fbOffsetInBytes));
|
|
|
|
// If VBlankStatusPtr is non-NULL then we know that the NT miniport
|
|
// will set the VBlankStatusPtr for us.
|
|
if (pThisDisplay->VBlankStatusPtr)
|
|
pGLInfo->dwFlags = GMVF_VBLANK_ENABLED;// Say that we are using VBLANKs
|
|
else
|
|
pGLInfo->dwFlags = 0;
|
|
|
|
pGLInfo->bPixelToBytesShift = (unsigned char)ppdev->cPelSize;
|
|
pGLInfo->ddFBSize = fbSizeInBytes;
|
|
pGLInfo->dwScreenBase = 0;
|
|
pGLInfo->dwOffscreenBase = fbOffsetInBytes;
|
|
|
|
pGLInfo->dwScreenWidth = ppdev->cxScreen; // Driver info
|
|
pGLInfo->dwScreenHeight = ppdev->cyScreen;
|
|
pGLInfo->dwVideoWidth = ppdev->cxMemory;
|
|
pGLInfo->dwVideoHeight = ppdev->cyMemory;
|
|
|
|
bSuccess = GET_REGISTRY_ULONG_FROM_STRING(
|
|
"HardwareInformation.CurrentPixelClockSpeed",
|
|
&dwRegistryValue);
|
|
if(!bSuccess)
|
|
{
|
|
DISPDBG((ERRLVL,"Error - can't determine pixel clock"));
|
|
dwRegistryValue = 0;
|
|
}
|
|
DISPDBG((DBGLVL,"Pixel clock frequency is %dHz", dwRegistryValue));
|
|
pGLInfo->PixelClockFrequency = dwRegistryValue;
|
|
|
|
bSuccess = GET_REGISTRY_ULONG_FROM_STRING(
|
|
"HardwareInformation.CurrentMemClockSpeed",
|
|
&dwRegistryValue);
|
|
if(!bSuccess)
|
|
{
|
|
DISPDBG((ERRLVL,"Error - can't determine memory clock"));
|
|
dwRegistryValue = 0;
|
|
}
|
|
|
|
DISPDBG((DBGLVL,"Memory clock frequency is %dHz", dwRegistryValue));
|
|
pGLInfo->MClkFrequency = dwRegistryValue;
|
|
|
|
if (ppdev->iBitmapFormat == BMF_8BPP)
|
|
{
|
|
DISPDBG((DBGLVL, "Desktop is 8 bits"));
|
|
pGLInfo->dwBpp = 8;
|
|
}
|
|
else if (ppdev->iBitmapFormat == BMF_16BPP)
|
|
{
|
|
DISPDBG((DBGLVL, "Desktop is 16 bits"));
|
|
pGLInfo->dwBpp = 16;
|
|
}
|
|
else if (ppdev->iBitmapFormat == BMF_24BPP)
|
|
{
|
|
DISPDBG((DBGLVL, "Desktop is 24 bits"));
|
|
pGLInfo->dwBpp = 24;
|
|
}
|
|
else
|
|
{
|
|
DISPDBG((DBGLVL, "Desktop is 32 bits"));
|
|
pGLInfo->dwBpp = 32;
|
|
}
|
|
|
|
pGLInfo->dwScreenWidthBytes = ppdev->lDelta;
|
|
|
|
if (pGLInfo->pRegs == 0)
|
|
{
|
|
DISPDBG ((WRNLVL, "__DDE_bSetupDDStructs: NULL register set"));
|
|
return (FALSE);
|
|
}
|
|
|
|
// Setup the information that is shared with the 32 bit side
|
|
// Control points to the RAMDAC
|
|
// pGLInfo is a pointer to the DisplayDriver state.
|
|
pThisDisplay->pGLInfo = pGLInfo;
|
|
pThisDisplay->control = (FLATPTR) pGLInfo->pRegs;
|
|
|
|
// NT uses offsets for its memory addresses
|
|
pThisDisplay->dwScreenFlatAddr = 0;
|
|
pThisDisplay->dwLocalBuffer = 0;
|
|
|
|
__DDE_BuildPixelFormat( pThisDisplay,
|
|
(LPGLINTINFO) pThisDisplay->pGLInfo,
|
|
&pThisDisplay->ddpfDisplay );
|
|
|
|
// Setup the display size information
|
|
// dwScreenWidth, dwScreenHeight = current resolution
|
|
// cxMemory = Pixels across for one scanline
|
|
// (not necessarily the same as the screen width)
|
|
// cyMemory = Scanline height of the memory
|
|
// dwScreenStart = First visible line of display
|
|
pThisDisplay->dwScreenWidth = pGLInfo->dwScreenWidth;
|
|
pThisDisplay->dwScreenHeight = pGLInfo->dwScreenHeight;
|
|
pThisDisplay->cxMemory = pGLInfo->dwScreenWidth;
|
|
|
|
pThisDisplay->dwScreenStart = pThisDisplay->dwScreenFlatAddr +
|
|
pGLInfo->dwScreenBase;
|
|
|
|
// Usefull constants used during blits.
|
|
if (pThisDisplay->ddpfDisplay.dwRGBBitCount == 24)
|
|
{
|
|
// The driver will detect these strange values and handle appropriately
|
|
pThisDisplay->bPixShift = 4;
|
|
pThisDisplay->bBppShift = 4;
|
|
pThisDisplay->dwBppMask = 4;
|
|
|
|
pThisDisplay->cyMemory = pGLInfo->ddFBSize /
|
|
(pThisDisplay->dwScreenWidth * 3);
|
|
}
|
|
else
|
|
{
|
|
// = 2,1,0 for 32,16,8 depth. Shifts needed to calculate bytes/pixel
|
|
pThisDisplay->bPixShift =
|
|
(BYTE)pThisDisplay->ddpfDisplay.dwRGBBitCount >> 4;
|
|
// = 0,1,2 for 32/16/8.
|
|
pThisDisplay->bBppShift = 2 - pThisDisplay->bPixShift;
|
|
// = 3,1,0 for 8,16,32 bpp
|
|
pThisDisplay->dwBppMask = 3 >> pThisDisplay->bPixShift;
|
|
|
|
pThisDisplay->cyMemory =
|
|
pGLInfo->ddFBSize /
|
|
(pThisDisplay->dwScreenWidth <<
|
|
(pThisDisplay->ddpfDisplay.dwRGBBitCount >> 4));
|
|
}
|
|
|
|
// On Windows NT, we manage a region of memory starting from 0
|
|
//(all pointers are offsets from the start of the mapped memory)
|
|
dwMemStart = pGLInfo->dwOffscreenBase;
|
|
dwMemEnd = pGLInfo->ddFBSize - 1;
|
|
|
|
// Round up the start pointer and round down the end pointer
|
|
dwMemStart = (dwMemStart + 3) & ~3;
|
|
dwMemEnd = dwMemEnd & ~3;
|
|
|
|
// Now make the end pointer inclusive
|
|
dwMemEnd -= 1;
|
|
|
|
DISPDBG((DBGLVL,"Heap Attributes:"));
|
|
DISPDBG((DBGLVL," Start of Heap Memory: 0x%lx",
|
|
pThisDisplay->LocalVideoHeap0Info.dwMemStart));
|
|
DISPDBG((DBGLVL," End of Heap Memory: 0x%lx",
|
|
pThisDisplay->LocalVideoHeap0Info.dwMemEnd));
|
|
|
|
// If we already have a heap setup and the mode has changed
|
|
// we free the Heap manager
|
|
if (pThisDisplay->bDDHeapManager)
|
|
{
|
|
if (pThisDisplay->bResetMode)
|
|
{
|
|
// The mode has been changed.
|
|
// We need to free the allocator and re-create it
|
|
_DX_LIN_UnInitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info);
|
|
|
|
// Start the allocator off again.
|
|
_DX_LIN_InitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info,
|
|
dwMemStart,
|
|
dwMemEnd);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// This must be the first instance of a created driver,
|
|
// so create the Heap and remember that it is created.
|
|
_DX_LIN_InitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info,
|
|
dwMemStart,
|
|
dwMemEnd);
|
|
pThisDisplay->bDDHeapManager = TRUE;
|
|
}
|
|
|
|
if(ppdev->flStatus & ENABLE_LINEAR_HEAP)
|
|
{
|
|
// save away the heap info we really need, we won't actually
|
|
// enable the DX managed heap until we get a
|
|
// DrvNotify(DN_DRAWING_BEGIN)
|
|
ppdev->heap.pvmLinearHeap = &pThisDisplay->LocalVideoHeap0Info;
|
|
ppdev->heap.cLinearHeaps = 1;
|
|
}
|
|
|
|
return TRUE;
|
|
} // __DDE_bSetupDDStructs
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// __DDE_bDestroyDDStructs
|
|
//
|
|
// Disable the linear allocator.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL
|
|
__DDE_bDestroyDDStructs (
|
|
P3_THUNKEDDATA* pThisDisplay )
|
|
{
|
|
// Release the linear allocator
|
|
if (pThisDisplay->bDDHeapManager)
|
|
{
|
|
_DX_LIN_UnInitialiseHeapManager(&pThisDisplay->LocalVideoHeap0Info);
|
|
}
|
|
|
|
// 3D Heap manager not available.
|
|
pThisDisplay->bDDHeapManager = FALSE;
|
|
|
|
// Reset the driver version to 0 so it will be filled in again.
|
|
pThisDisplay->dwDXVersion = 0;
|
|
|
|
return TRUE;
|
|
|
|
} // __DDE_bDestroyDDStructs
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// _DD_DDE_CreatePPDEV
|
|
//
|
|
// These functions are called in sync with the creation/destruction of the pDev
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL
|
|
_DD_DDE_CreatePPDEV(
|
|
PDEV* ppdev)
|
|
{
|
|
P3_THUNKEDDATA* pThisDisplay;
|
|
|
|
DISPDBG((DBGLVL,"*** In _DD_DDE_CreatePPDEV"));
|
|
|
|
ASSERTDD(ppdev->thunkData == NULL,
|
|
"ERROR: thunkData already created for this pDev??");
|
|
|
|
// initialize the DX context which will be used by the display driver
|
|
// context switcher. We need a reference count because there is a case
|
|
// when a second, temporary, context would otherwise be created (when
|
|
// enabling the second adapter in a m-monitor system), first scrubbing
|
|
// out the old context ID, then invalidating the new one when it is
|
|
// deleted!
|
|
ppdev->DDContextID = -1;
|
|
ppdev->DDContextRefCount = 0;
|
|
|
|
// Allocate our ppdev
|
|
ppdev->thunkData = (PVOID)HEAP_ALLOC(HEAP_ZERO_MEMORY,
|
|
sizeof(P3_THUNKEDDATA),
|
|
ALLOC_TAG_DX(D));
|
|
if (ppdev->thunkData == NULL)
|
|
{
|
|
DISPDBG((ERRLVL, "_DD_DDE_CreatePPDEV: thunkdata alloc failed"));
|
|
return (FALSE);
|
|
}
|
|
|
|
// Our ppdev is called pThisDisplay
|
|
pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
|
|
pThisDisplay->ppdev = ppdev;
|
|
|
|
pThisDisplay->pGLInfo = (PVOID)HEAP_ALLOC(HEAP_ZERO_MEMORY,
|
|
sizeof(GlintInfo),
|
|
ALLOC_TAG_DX(E));
|
|
if (pThisDisplay->pGLInfo == NULL)
|
|
{
|
|
DISPDBG((ERRLVL, "_DD_DDE_CreatePPDEV: pGLInfo alloc failed"));
|
|
|
|
EngFreeMem (pThisDisplay);
|
|
ppdev->thunkData = NULL;
|
|
|
|
return (FALSE);
|
|
}
|
|
|
|
//@@BEGIN_DDKSPLIT
|
|
// W9X DX version is setup in the display driver.
|
|
//@@END_DDKSPLIT
|
|
|
|
// On Windows W2000 DX is always at least DX7
|
|
pThisDisplay->dwDXVersion = DX7_RUNTIME;
|
|
|
|
GetChipInfoForDDraw(ppdev,
|
|
&pThisDisplay->pGLInfo->dwRenderChipID,
|
|
&pThisDisplay->pGLInfo->dwRenderChipRev,
|
|
&pThisDisplay->pGLInfo->dwRenderFamily,
|
|
&pThisDisplay->pGLInfo->dwGammaRev);
|
|
|
|
DISPDBG((DBGLVL,"RenderChip: 0x%x, RenderFamily: 0x%x",
|
|
pThisDisplay->pGLInfo->dwRenderChipID,
|
|
pThisDisplay->pGLInfo->dwRenderFamily));
|
|
|
|
return TRUE;
|
|
} // _DD_DDE_CreatePPDEV
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// _DD_DDE_ResetPPDEV
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _DD_DDE_ResetPPDEV(PDEV* ppdevOld, PDEV* ppdevNew)
|
|
{
|
|
P3_THUNKEDDATA* pThisDisplayOld = (P3_THUNKEDDATA*)ppdevOld->thunkData;
|
|
P3_THUNKEDDATA* pThisDisplayNew = (P3_THUNKEDDATA*)ppdevNew->thunkData;
|
|
|
|
DISPDBG((DBGLVL,"_DD_DDE_ResetPPDEV: "
|
|
"pThisDispayOld: 0x%x, pThisDisplayNew: 0x%x",
|
|
pThisDisplayOld, pThisDisplayNew));
|
|
|
|
} // _DD_DDE_ResetPPDEV
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// _DD_DDE_DestroyPPDEV
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void _DD_DDE_DestroyPPDEV(PDEV* ppdev)
|
|
{
|
|
P3_THUNKEDDATA* pThisDisplay = (P3_THUNKEDDATA*)ppdev->thunkData;
|
|
|
|
#if DBG
|
|
g_pThisTemp = NULL;
|
|
#endif
|
|
|
|
if (pThisDisplay)
|
|
{
|
|
// The 32 bit side will have allocated memory for use as global
|
|
// D3D/DD Driver data. Free it if it is there
|
|
if (pThisDisplay->pD3DHALCallbacks16)
|
|
{
|
|
SHARED_HEAP_FREE(&pThisDisplay->pD3DHALCallbacks16,
|
|
&pThisDisplay->pD3DHALCallbacks32,
|
|
TRUE);
|
|
|
|
DISPDBG((DBGLVL,"Freed pThisDisplay->pD3DHALCallbacks32"));
|
|
}
|
|
|
|
if (pThisDisplay->pD3DDriverData16)
|
|
{
|
|
SHARED_HEAP_FREE(&pThisDisplay->pD3DDriverData16,
|
|
&pThisDisplay->pD3DDriverData32,
|
|
TRUE);
|
|
|
|
DISPDBG((DBGLVL,"Freed pThisDisplay->pD3DDriverData32"));
|
|
}
|
|
|
|
pThisDisplay->lpD3DGlobalDriverData = 0;
|
|
pThisDisplay->lpD3DHALCallbacks = 0;
|
|
|
|
if (pThisDisplay->pGLInfo)
|
|
{
|
|
EngFreeMem (pThisDisplay->pGLInfo);
|
|
pThisDisplay->pGLInfo = NULL;
|
|
DISPDBG((DBGLVL,"Freed pThisDisplay->pGLInfo"));
|
|
}
|
|
|
|
EngFreeMem (pThisDisplay);
|
|
pThisDisplay = NULL;
|
|
DISPDBG((DBGLVL,"Freed pThisDisplay"));
|
|
}
|
|
|
|
// Clear the pointer
|
|
ppdev->thunkData = NULL;
|
|
|
|
} // _DD_DDE_DestroyPPDEV
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// _DD_DDE_vAssertModeDirectDraw
|
|
//
|
|
// This function is called by enable.c when entering or leaving the
|
|
// DOS full-screen character mode.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID
|
|
_DD_DDE_vAssertModeDirectDraw(
|
|
PDEV* ppdev,
|
|
BOOL bEnabled)
|
|
{
|
|
P3_THUNKEDDATA* pThisDisplay = (P3_THUNKEDDATA*)ppdev->thunkData;
|
|
|
|
DISPDBG((DBGLVL, "_DD_DDE_vAssertModeDirectDraw: enter"));
|
|
|
|
#if DX7_TEXMANAGEMENT
|
|
// Mark all managed surfaces as dirty as we've lost
|
|
// everything living in the videomemory
|
|
|
|
_DD_TM_EvictAllManagedTextures(pThisDisplay);
|
|
|
|
#endif
|
|
|
|
} // _DD_DDE_vAssertModeDirectDraw
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// _DD_DDE_bEnableDirectDraw
|
|
//
|
|
// This function is called by enable.c when the mode is first initialized,
|
|
// right after the miniport does the mode-set.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
BOOL _DD_DDE_bEnableDirectDraw(
|
|
PDEV* ppdev)
|
|
{
|
|
DISPDBG((DBGLVL, "_DD_DDE_bEnableDirectDraw: enter"));
|
|
|
|
// DirectDraw is all set to be used on this card:
|
|
ppdev->flStatus |= STAT_DIRECTDRAW;
|
|
|
|
return(TRUE);
|
|
} // _DD_DDE_bEnableDirectDraw
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// _DD_DDE_vDisableDirectDraw
|
|
//
|
|
// This function is called by enable.c when the driver is shutting down.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID _DD_DDE_vDisableDirectDraw(
|
|
PDEV* ppdev)
|
|
{
|
|
DISPDBG((DBGLVL, "_DD_DDE_vDisableDirectDraw: enter"));
|
|
} // _DD_DDE_vDisableDirectDraw
|
|
|
|
//-----------------------------Public Routine----------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// DrvEnableDirectDraw
|
|
//
|
|
// Enables hardware for DirectDraw use.
|
|
//
|
|
// GDI calls DrvEnableDirectDraw to obtain pointers to the DirectDraw callbacks
|
|
// that the driver supports. The driver should set the function pointer members
|
|
// of DD_CALLBACKS, DD_SURFACECALLBACKS, and DD_PALETTECALLBACKS to point to
|
|
// those functions that it implements. A driver should also set the
|
|
// corresponding bit fields in the dwFlags members of these structures for all
|
|
// supported callbacks.
|
|
//
|
|
// A driver's DrvEnableDirectDraw implementation can also dedicate hardware
|
|
// resources such as display memory for use by DirectDraw only.
|
|
//
|
|
// DrvEnableDirectDraw returns TRUE if it succeeds; otherwise, it returns FALSE
|
|
//
|
|
// Parameters
|
|
//
|
|
// dhpdev
|
|
// Handle to the PDEV returned by the driver's DrvEnablePDEV routine.
|
|
// pCallBacks
|
|
// Points to the DD_CALLBACKS structure to be initialized by the
|
|
// driver.
|
|
// pSurfaceCallBacks
|
|
// Points to the DD_SURFACECALLBACKS structure to be initialized by
|
|
// the driver.
|
|
// pPaletteCallBacks
|
|
// Points to the DD_PALETTECALLBACKS structure to be initialized by
|
|
// the driver.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
BOOL DrvEnableDirectDraw(
|
|
DHPDEV dhpdev,
|
|
DD_CALLBACKS* pCallBacks,
|
|
DD_SURFACECALLBACKS* pSurfaceCallBacks,
|
|
DD_PALETTECALLBACKS* pPaletteCallBacks)
|
|
{
|
|
PDEV* ppdev;
|
|
BOOL bRet;
|
|
DWORD dwResult;
|
|
P3_THUNKEDDATA* pThisDisplay;
|
|
DWORD *theVBlankThing, *bOverlayEnabled;
|
|
DWORD *VBLANKUpdateOverlay;
|
|
DWORD *VBLANKUpdateOverlayWidth;
|
|
DWORD *VBLANKUpdateOverlayHeight;
|
|
DWORD Buffers;
|
|
|
|
ppdev = (PDEV*) dhpdev;
|
|
pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
|
|
|
|
if (!bSetupOffscreenForDDraw (FALSE,
|
|
ppdev,
|
|
&theVBlankThing,
|
|
&bOverlayEnabled,
|
|
&VBLANKUpdateOverlay,
|
|
&VBLANKUpdateOverlayWidth,
|
|
&VBLANKUpdateOverlayHeight))
|
|
{
|
|
DISPDBG((ERRLVL, "DrvEnableDirectDraw: "
|
|
"bSetupOffscreenForDDraw failed, but continuing"));
|
|
//return (FALSE);
|
|
}
|
|
|
|
pThisDisplay->VBlankStatusPtr = theVBlankThing;
|
|
pThisDisplay->bOverlayEnabled = bOverlayEnabled;
|
|
pThisDisplay->bVBLANKUpdateOverlay = VBLANKUpdateOverlay;
|
|
pThisDisplay->VBLANKUpdateOverlayWidth = VBLANKUpdateOverlayWidth;
|
|
pThisDisplay->VBLANKUpdateOverlayHeight = VBLANKUpdateOverlayHeight;
|
|
|
|
#if DBG
|
|
// Read in the registry variable for the debug level
|
|
{
|
|
// Get the Debuglevel for DirectX
|
|
bRet = GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.Debug", &dwResult);
|
|
if (bRet == TRUE)
|
|
{
|
|
P3R3DX_DebugLevel = (LONG)dwResult;
|
|
}
|
|
else
|
|
{
|
|
P3R3DX_DebugLevel = 0;
|
|
}
|
|
|
|
DISPDBG((WRNLVL,"Setting DebugLevel to 0x%x", P3R3DX_DebugLevel));
|
|
}
|
|
#endif
|
|
|
|
// Create context with >2 sub-buffers for Interupt driven DMA.
|
|
bRet =GET_REGISTRY_ULONG_FROM_STRING("Direct3DHAL.SubBuffers", &dwResult);
|
|
if ((dwResult == 0) || (bRet == FALSE))
|
|
{
|
|
// Default
|
|
Buffers = DEFAULT_SUBBUFFERS;
|
|
}
|
|
else
|
|
{
|
|
if (dwResult > MAX_SUBBUFFERS)
|
|
{
|
|
Buffers = MAX_SUBBUFFERS;
|
|
}
|
|
else
|
|
{
|
|
Buffers = dwResult;
|
|
}
|
|
|
|
if (Buffers < 2)
|
|
{
|
|
Buffers = 2;
|
|
}
|
|
}
|
|
|
|
pThisDisplay->pGLInfo->dw3DDMABufferSize = 0;
|
|
pThisDisplay->pGLInfo->dw3DDMABufferPhys = 0;
|
|
pThisDisplay->pGLInfo->dw3DDMABufferVirt = 0;
|
|
|
|
// Allocate a DMA Buffer on Win2K
|
|
DDGetFreeDMABuffer(&pThisDisplay->pGLInfo->dw3DDMABufferPhys,
|
|
&pThisDisplay->pGLInfo->dw3DDMABufferVirt,
|
|
&pThisDisplay->pGLInfo->dw3DDMABufferSize);
|
|
|
|
if (pThisDisplay->pGLInfo->dw3DDMABufferSize != 0)
|
|
{
|
|
DISPDBG((DBGLVL,"Allocated DMA Buffer:- "
|
|
"Phys:0x%x, Virt:0x%x, Size:0x%x",
|
|
pThisDisplay->pGLInfo->dw3DDMABufferPhys,
|
|
pThisDisplay->pGLInfo->dw3DDMABufferVirt,
|
|
pThisDisplay->pGLInfo->dw3DDMABufferSize));
|
|
}
|
|
else
|
|
{
|
|
DISPDBG((WRNLVL,"Failed to allocate DMA Buffer!"));
|
|
}
|
|
|
|
if(ppdev->DDContextID == -1)
|
|
{
|
|
// we don't have a DDraw context: create one now
|
|
ppdev->DDContextID = GlintAllocateNewContext(ppdev,
|
|
NULL,
|
|
0,
|
|
Buffers,
|
|
NULL,
|
|
ContextType_None);
|
|
if(ppdev->DDContextID != -1)
|
|
{
|
|
++ppdev->DDContextRefCount;
|
|
|
|
DISPDBG((DBGLVL, "<%13s, %4d>: DrvEnableDirectDraw: "
|
|
"Created DDraw context, current DX context "
|
|
"count = %d for ppdev %p",
|
|
__FILE__, __LINE__,
|
|
ppdev->DDContextRefCount, ppdev));
|
|
}
|
|
}
|
|
|
|
if (ppdev->DDContextID < 0)
|
|
{
|
|
DISPDBG((ERRLVL, "ERROR: failed to allocate DDRAW context"));
|
|
return(FALSE);
|
|
}
|
|
|
|
DISPDBG((DBGLVL," Created DD Register context: 0x%x",
|
|
ppdev->DDContextID));
|
|
|
|
if (!__DDE_bSetupDDStructs (pThisDisplay, TRUE))
|
|
{
|
|
vGlintFreeContext (ppdev, ppdev->DDContextID);
|
|
DISPDBG((ERRLVL, "ERROR: DrvEnableDirectDraw: "
|
|
"__DDE_bSetupDDStructs failed"));
|
|
return (FALSE);
|
|
}
|
|
|
|
if (!_DD_InitDDHAL32Bit (pThisDisplay))
|
|
{
|
|
vGlintFreeContext (ppdev, ppdev->DDContextID);
|
|
DISPDBG((ERRLVL, "ERROR: DrvEnableDirectDraw: "
|
|
"_DD_InitDDHAL32Bit failed"));
|
|
return (FALSE);
|
|
}
|
|
|
|
// Set the flag that says we have to handle a mode change.
|
|
// This will cause the chip to be initialised properly at the
|
|
// right time.
|
|
pThisDisplay->bResetMode = TRUE;
|
|
pThisDisplay->bStartOfDay = TRUE;
|
|
pThisDisplay->pGLInfo->dwDirectXState = DIRECTX_LASTOP_UNKNOWN;
|
|
|
|
// Fill in the function pointers at start of day. We copy these from
|
|
// the Initialisation done in _DD_InitDDHAL32Bit. It's OK to do this
|
|
// because on a Windows NT compile the structures should match
|
|
memcpy(pCallBacks,
|
|
&pThisDisplay->DDHALCallbacks,
|
|
sizeof(DD_CALLBACKS));
|
|
|
|
memcpy(pSurfaceCallBacks,
|
|
&pThisDisplay->DDSurfCallbacks,
|
|
sizeof(DD_SURFACECALLBACKS));
|
|
|
|
// Note that we don't call 'vGetDisplayDuration' here, for a couple of
|
|
// reasons:
|
|
//
|
|
// o Because the system is already running, it would be disconcerting
|
|
// to pause the graphics for a good portion of a second just to read
|
|
// the refresh rate;
|
|
// o More importantly, we may not be in graphics mode right now.
|
|
//
|
|
// For both reasons, we always measure the refresh rate when we switch
|
|
// to a new mode.
|
|
|
|
return(TRUE);
|
|
|
|
} // DrvEnableDirectDraw
|
|
|
|
//-----------------------------Public Routine----------------------------------
|
|
//
|
|
// ***************************WIN NT ONLY**********************************
|
|
//
|
|
// DrvDisableDirectDraw
|
|
//
|
|
// Disables hardware for DirectDraw use.
|
|
//
|
|
// GDI calls DrvDisableDirectDraw when the last DirectDraw application has
|
|
// finished running. A driver's DrvDisableDirectDraw implementation should
|
|
// clean up any software resources and reclaim any hardware resources that
|
|
// the driver dedicated to DirectDraw in DrvEnableDirectDraw.
|
|
//
|
|
// Parameters
|
|
// dhpdev
|
|
// Handle to the PDEV that was returned by the driver's
|
|
// DrvEnablePDEV routine.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
VOID
|
|
DrvDisableDirectDraw(
|
|
DHPDEV dhpdev)
|
|
{
|
|
PDEV* ppdev;
|
|
P3_THUNKEDDATA* pThisDisplay;
|
|
|
|
ppdev = (PDEV*) dhpdev;
|
|
pThisDisplay = (P3_THUNKEDDATA*) ppdev->thunkData;
|
|
|
|
// Only do all this stuff if we have not already been disabled.
|
|
// Note that when running NT4 without SP3, this function can be called
|
|
// more times than DrvEnableDirectDraw.
|
|
if (pThisDisplay != NULL)
|
|
{
|
|
// Re-enable GDI off-screen bitmaps
|
|
(void) bSetupOffscreenForDDraw (TRUE,
|
|
ppdev,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
|
|
// Free all memory
|
|
(void) __DDE_bDestroyDDStructs (pThisDisplay);
|
|
|
|
if(ppdev->DDContextRefCount > 0)
|
|
{
|
|
if(--ppdev->DDContextRefCount == 0)
|
|
{
|
|
vGlintFreeContext (ppdev, ppdev->DDContextID);
|
|
DISPDBG((DBGLVL,"Freed DDraw context: 0x%x",
|
|
ppdev->DDContextID));
|
|
|
|
ppdev->DDContextID = -1;
|
|
|
|
DISPDBG((DBGLVL, "<%13s, %4d>: DrvDisableDirectDraw:"
|
|
" Deleted DDraw context, current DX context"
|
|
" count = %d for ppdev %p",
|
|
__FILE__, __LINE__,
|
|
ppdev->DDContextRefCount, ppdev));
|
|
}
|
|
}
|
|
|
|
DDFreeDMABuffer((void*)(ULONG_PTR)pThisDisplay->pGLInfo->dw3DDMABufferPhys);
|
|
|
|
}
|
|
} // DrvDisableDirectDraw
|
|
|
|
#endif // WNT_DDRAW
|