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.
 
 
 
 
 
 

1645 lines
69 KiB

/******************************Module*Header**********************************\
*
* *******************
* * GDI SAMPLE CODE *
* *******************
*
* Module Name: glntinit.c
*
* Content: Initialisation for the GLINT chip.
*
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "precomp.h"
#include "pxrx.h"
#define FOUR_MB (4*1024*1024)
#define AGP_LONG_READ_DISABLE (1<<3)
/******************************Public*Routine******************************\
* VOID vInitCoreRegisters
*
\**************************************************************************/
VOID vInitCoreRegisters(PPDEV ppdev)
{
ULONG f, b;
GLINT_DECL;
if (glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITE)
{
f = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT) ? 1 : 0;
b = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK ) ? 1 : 0;
}
else
{
f = b = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT) ? 1 : 0;
}
glintInfo->foregroundColour = 0x33BADBAD;
glintInfo->backgroundColour = 0x33BAAAAD;
glintInfo->config2D = 0;
glintInfo->backBufferXY = MAKEDWORD_XY(0, ppdev->cyScreen); // This is set properly in bInitializeGlint
glintInfo->frontRightBufferXY = MAKEDWORD_XY(0, ppdev->cyScreen);
glintInfo->backRightBufferXY = MAKEDWORD_XY(0, ppdev->cyScreen);
glintInfo->fbDestMode = (1 << 8) | (1 << 1) | (f << 12) | (b << 14);
if (glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITE)
{
glintInfo->fbDestMode |= (b << 16) | (f << 18);
}
glintInfo->fbDestAddr[0] = 0x00000000;
glintInfo->fbDestAddr[1] = 0x00000000;
glintInfo->fbDestAddr[2] = 0x00000000;
glintInfo->fbDestAddr[3] = 0x00000000;
glintInfo->fbDestWidth[0] = ppdev->cxMemory;
glintInfo->fbDestWidth[1] = ppdev->cxMemory;
glintInfo->fbDestWidth[2] = ppdev->cxMemory;
glintInfo->fbDestWidth[3] = ppdev->cxMemory;
glintInfo->fbDestOffset[0] = 0;
glintInfo->fbDestOffset[1] = 0;
glintInfo->fbDestOffset[2] = 0;
glintInfo->fbDestOffset[3] = 0;
glintInfo->fbWriteAddr[0] = 0x00000000;
glintInfo->fbWriteAddr[1] = 0x00000000;
glintInfo->fbWriteAddr[2] = 0x00000000;
glintInfo->fbWriteAddr[3] = 0x00000000;
glintInfo->fbWriteWidth[0] = ppdev->cxMemory;
glintInfo->fbWriteWidth[1] = ppdev->cxMemory;
glintInfo->fbWriteWidth[2] = ppdev->cxMemory;
glintInfo->fbWriteWidth[3] = ppdev->cxMemory;
glintInfo->fbWriteOffset[0] = 0;
glintInfo->fbWriteOffset[1] = 0;
glintInfo->fbWriteOffset[2] = 0;
glintInfo->fbWriteOffset[3] = 0;
glintInfo->fbSourceAddr = 0x00000000;
glintInfo->fbSourceWidth = ppdev->cxMemory;
glintInfo->fbSourceOffset = 0;
glintInfo->lutMode = 0;
glintInfo->lastLine = 0;
glintInfo->render2Dpatching = 0;
pxrxSetupDualWrites_Patching(ppdev);
pxrxRestore2DContext(ppdev, TRUE);
// Set the cache flag to say that there is no cache info
ppdev->cFlags = 0;
} // vInitCoreRegisters
/******************************Public*Routine******************************\
* BOOL bAllocateGlintInfo
*
* Allocate ppdev->glintInfo and initialise the board info. We need to do
* this as early as possible because we're getting to the point where we
* need to know the board type very early.
\**************************************************************************/
BOOL bAllocateGlintInfo(PPDEV ppdev)
{
GlintDataPtr glintInfo;
ULONG Length;
// Allocate and initialize ppdev->glintInfo.
// We store GLINT specific stuff in this structure.
glintInfo = (PVOID)ENGALLOCMEM(FL_ZERO_MEMORY,
sizeof(GlintDataRec),
ALLOC_TAG_GDI(A));
if (glintInfo == NULL)
{
DISPDBG((ERRLVL, "cannot allocate memory for glintInfo struct"));
return(FALSE);
}
glintInfo->bGlintCoreBusy = TRUE;
ppdev->glintInfo = (PVOID)glintInfo;
// retrieve the PCI configuration information and local buffer size
Length = sizeof(Glint_Device_Info);
if (EngDeviceIoControl(ppdev->hDriver,
IOCTL_VIDEO_QUERY_DEVICE_INFO,
NULL,
0,
(PVOID)&(glintInfo->deviceInfo),
Length,
&Length))
{
DISPDBG((ERRLVL, "QUERY_DEVICE_INFO failed."));
return(FALSE);
}
return(TRUE);
} // bAllocateGlintInfo
/******************************Public*Routine******************************\
* BOOL bInitializeGlint
*
* Called to load the initial values into the chip. We assume the hardware
* has been mapped. All the relevant stuff should be hanging off ppdev. We
* also sort out all the GLINT capabilities etc.
\**************************************************************************/
BOOL bInitializeGlint(PPDEV ppdev)
{
pGlintControlRegMap pCtrlRegs;
pGlintControlRegMap pCtrlRegsVTG;
pGlintControlRegMap pCtrlRegsOdd;
pGlintCoreRegMap pCoreRegs;
pGlintCoreRegMap pCoreRegsRd;
pGlintCoreRegMap pCoreRegsOdd;
DSURF* pdsurf;
OH *poh = NULL;
LONG cPelSize;
LONG cx, cy;
LONG i, j;
ULONG width;
ULONG ulValue;
BOOL bExists;
BOOL bCreateBackBuffer;
BOOL bCreateStereoBuffers;
ULONG Length;
LONG FinalTag;
GLINT_DECL;
DISPDBG((DBGLVL, "bInitializeGlint: fbsize: 0x%x", ppdev->FrameBufferLength));
glintInfo->ddCtxtId = -1; // initialize to no context
glintInfo->LineDMABuffer.virtAddr = 0; // Initialise these values
glintInfo->LineDMABuffer.size = 0;
glintInfo->PXRXDMABuffer.virtAddr = 0;
glintInfo->PXRXDMABuffer.size = 0;
ppdev->DMABuffer.pphysStart.HighPart = 0;
ppdev->DMABuffer.pphysStart.LowPart = 0;
ppdev->DMABuffer.cb = 0;
ppdev->DMABuffer.pulStart = NULL;
ppdev->DMABuffer.pulCurrent = NULL;
ppdev->DMABuffer.pulEnd = NULL;
Length = sizeof(GENERAL_DMA_BUFFER);
ulValue = 1;
if (EngDeviceIoControl(ppdev->hDriver,
IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER,
&ulValue,
sizeof(ulValue),
(PVOID)&(glintInfo->LineDMABuffer),
Length,
&Length))
{
DISPDBG((ERRLVL, "QUERY_LINE_DMA_BUFFER failed."));
DISPDBG((ERRLVL, "FATAL ERROR: DRIVER REQUIRES DMA BUFFER FOR 2D"
" - UNLOADING DRIVER"));
return(FALSE);
}
bExists = bGlintQueryRegistryValueUlong( ppdev, L"PXRX.DisableDMA", &i );
if ((bExists && !i) || !bExists)
{
Length = sizeof(GENERAL_DMA_BUFFER);
ulValue = 2;
if (EngDeviceIoControl(ppdev->hDriver,
IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER,
&ulValue,
sizeof(ulValue),
(PVOID) &glintInfo->PXRXDMABuffer,
Length,
&Length))
{
DISPDBG((DBGLVL, "QUERY_DMA_BUFFER failed for the PXRX buffer."));
return FALSE;
}
DISPDBG((DBGLVL, "QUERY_DMA_BUFFER(PxRx): P:0x%X:%08X, V:0x%08X, S:%dKb, %s",
glintInfo->PXRXDMABuffer.physAddr.HighPart, glintInfo->PXRXDMABuffer.physAddr.LowPart,
glintInfo->PXRXDMABuffer.virtAddr, glintInfo->PXRXDMABuffer.size / 1024,
glintInfo->PXRXDMABuffer.cacheEnabled ? "Cached" : "Uncached"));
}
#if DBG
else
{
GENERAL_DMA_BUFFER dmaBuff;
Length = sizeof(GENERAL_DMA_BUFFER);
ulValue = 2;
if( EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER,
&ulValue, sizeof(ulValue), (PVOID) &dmaBuff,
Length, &Length) ) {
DISPDBG((ERRLVL, "QUERY_DMA_BUFFER failed for the PXRX buffer."));
return FALSE;
}
DISPDBG((DBGLVL, "QUERY_DMA_BUFFER(???): P:0x%X:%08X, V:0x%08X, S:%dKb, %s",
dmaBuff.physAddr.HighPart, dmaBuff.physAddr.LowPart, dmaBuff.virtAddr, dmaBuff.size / 1024,
dmaBuff.cacheEnabled ? "Cached" : "Uncached"));
}
#endif
//@@BEGIN_DDKSPLIT
// TMM: Temporary until we fix s/w cursors. Disable s/w cursor.
ppdev->flStatus &= ~ENABLE_POINTER_CACHE;
//@@END_DDKSPLIT
// Clear the patching flags to begin with
glintInfo->pxrxFlags &= ~(PXRX_FLAGS_PATCHING_FRONT | PXRX_FLAGS_PATCHING_BACK);
// the 2D driver can use the line buffer for other things as well, such as for text rendering
ppdev->DMABuffer.pphysStart = glintInfo->LineDMABuffer.physAddr;
ppdev->DMABuffer.cb = glintInfo->LineDMABuffer.size;
ppdev->DMABuffer.pulStart = glintInfo->LineDMABuffer.virtAddr;
ppdev->DMABuffer.pulCurrent = glintInfo->LineDMABuffer.virtAddr;
ppdev->DMABuffer.pulEnd = ppdev->DMABuffer.pulStart + glintInfo->LineDMABuffer.size - 1;
// set-up the DMA board status - we'll program the registers later
ppdev->g_GlintBoardStatus = GLINT_DMA_COMPLETE;
// Init whether or not GDI is allowed to access framebuffer.
// This must be a variable as it is affected by overlays.
glintInfo->GdiCantAccessFramebuffer = ((ppdev->flCaps & CAPS_SPARSE_SPACE) == CAPS_SPARSE_SPACE);
DISPDBG((WRNLVL, "deviceInfo: GdiCantAccessFramebuffer %d", glintInfo->GdiCantAccessFramebuffer));
DISPDBG((WRNLVL, "deviceInfo: VendorId: 0x%x, DevId 0x%x, GammaId 0x%x, RevId %d, SubId %d, SubVId %d, lbuf len 0x%x, lbuf width %d",
glintInfo->deviceInfo.VendorId,
glintInfo->deviceInfo.DeviceId,
glintInfo->deviceInfo.GammaRevId,
glintInfo->deviceInfo.RevisionId,
glintInfo->deviceInfo.SubsystemId,
glintInfo->deviceInfo.SubsystemVendorId,
glintInfo->deviceInfo.LocalbufferLength,
glintInfo->deviceInfo.LocalbufferWidth));
// collect flags as we initialize so zero it here
glintInfo->flags = 0;
//@@BEGIN_DDKSPLIT
#if 0
// Try to establish color space double buffering. The actual method
// depends on the RAMDAC so call the appropriate routine depending on
// the one we support.
//
bExists = ppdev->pgfnPointerCheckCSBuffering(ppdev);
if (bExists)
{
glintInfo->flags |= GLICAP_COLOR_SPACE_DBL_BUF;
}
#endif
//@@END_DDKSPLIT
// optional DrvCopyBits acceleration for downloads
ppdev->pgfnCopyXferImage = NULL;
ppdev->pgfnCopyXfer24bpp = NULL;
ppdev->pgfnCopyXfer16bpp = NULL;
ppdev->pgfnCopyXfer8bppLge = NULL;
ppdev->pgfnCopyXfer8bpp = NULL;
ppdev->pgfnCopyXfer4bpp = NULL;
// optional NT5 acceleration functions
#if(_WIN32_WINNT >= 0x500)
ppdev->pgfnGradientFillRect = NULL;
ppdev->pgfnTransparentBlt = NULL;
ppdev->pgfnAlphaBlend = NULL;
#endif
//@@BEGIN_DDKSPLIT
// if we're simulating from boot-up then it's OK to use our preferred text method
// HIDEYUKN, temporary disable host memory cache, until figure out more detail.
// ppdev->PreferredGlyphRenderingMethod = GLYPH_HOSTMEM_CACHE;
//@@END_DDKSPLIT
glintInfo->usePXRXdma = USE_PXRX_DMA_FIFO;
pxrxSetupFunctionPointers( ppdev );
// Do the translates for all the GLINT registers we use. For dual-TX
// pCoreRegs points at core registers through Delta
// pCtrlRegs points at Delta
// pCtrlRegsVTG points at the TX with the RAMDAC
// pCtrlRegsOdd points at the non-VTG TX (odd owned scanlines for 3D)
//
pCtrlRegs =
pCtrlRegsVTG = (pGlintControlRegMap)ppdev->pulCtrlBase[0];
pCtrlRegsOdd = (pGlintControlRegMap)ppdev->pulCtrlBase[1];
pCoreRegs = &(pCtrlRegs->coreRegs);
pCoreRegsOdd = &(pCtrlRegsOdd->coreRegs);
pCoreRegsRd = &(pCtrlRegsVTG->coreRegs);
glintInfo->BroadcastMask2D = DELTA_BROADCAST_TO_CHIP(0);
glintInfo->BroadcastMask3D = DELTA_BROADCAST_TO_BOTH_CHIPS;
if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
{
glintInfo->BroadcastMask2D = DELTA_BROADCAST_TO_BOTH_CHIPS;
pCtrlRegsVTG = (pGlintControlRegMap)ppdev->pulCtrlBase[1];
}
ppdev->pulRamdacBase = (PVOID)&(pCtrlRegsVTG->ExternalVideo);
// FIFO registers. Translate all possible tags
FinalTag = __MaximumGlintTagValue;
// record the maximum number if free FIFO entries
if( GLINT_GAMMA_PRESENT ) {
glintInfo->MaxInFifoEntries = MAX_GAMMA_FIFO_ENTRIES;
} else {
glintInfo->MaxInFifoEntries = MAX_P3_FIFO_ENTRIES;
}
// Chip tags may be read/written from different address spaces
for (i = 0; i < __DeltaTagV0Fixed0; ++i)
{
glintInfo->regs.tagwr[i] =
TRANSLATE_ADDR(&(pCoreRegs->tag[i]));
glintInfo->regs.tagrd[i] =
TRANSLATE_ADDR(&(pCoreRegsRd->tag[i]));
}
// Delta tags are read/written from the same address space
for (i = __DeltaTagV0Fixed0; i <= FinalTag; ++i)
{
glintInfo->regs.tagwr[i] =
TRANSLATE_ADDR(&(pCoreRegs->tag[i]));
glintInfo->regs.tagrd[i] =
TRANSLATE_ADDR(&(pCoreRegs->tag[i]));
}
// non-FIFO control registers
glintInfo->regs.LBMemoryCtl =
TRANSLATE_ADDR(&(pCtrlRegsVTG->LBMemoryCtl));
glintInfo->regs.LBMemoryEDO =
TRANSLATE_ADDR(&(pCtrlRegsVTG->LBMemoryEDO));
glintInfo->regs.FBMemoryCtl =
TRANSLATE_ADDR(&(pCtrlRegsVTG->FBMemoryCtl));
glintInfo->regs.FBModeSel =
TRANSLATE_ADDR(&(pCtrlRegs->FBModeSel));
glintInfo->regs.FBModeSelOdd =
TRANSLATE_ADDR(&(pCtrlRegsOdd->FBModeSel));
glintInfo->regs.VTGHLimit =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHLimit));
glintInfo->regs.VTGHSyncStart =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHSyncStart));
glintInfo->regs.VTGHSyncEnd =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHSyncEnd));
glintInfo->regs.VTGHBlankEnd =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHBlankEnd));
glintInfo->regs.VTGHGateStart =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHGateStart));
glintInfo->regs.VTGHGateEnd =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHGateEnd));
glintInfo->regs.VTGVLimit =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVLimit));
glintInfo->regs.VTGVSyncStart =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVSyncStart));
glintInfo->regs.VTGVSyncEnd =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVSyncEnd));
glintInfo->regs.VTGVBlankEnd =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVBlankEnd));
glintInfo->regs.VTGVGateStart =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVGateStart));
glintInfo->regs.VTGVGateEnd =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVGateEnd));
glintInfo->regs.VTGPolarity =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGPolarity));
glintInfo->regs.VTGVLineNumber =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVLineNumber));
glintInfo->regs.VTGFrameRowAddr =
TRANSLATE_ADDR(&(pCtrlRegs->VTGFrameRowAddr));
glintInfo->regs.VTGFrameRowAddrOdd =
TRANSLATE_ADDR(&(pCtrlRegsOdd->VTGFrameRowAddr));
glintInfo->regs.InFIFOSpace =
TRANSLATE_ADDR(&(pCtrlRegs->InFIFOSpace));
glintInfo->regs.OutFIFOWords =
TRANSLATE_ADDR(&(pCtrlRegs->OutFIFOWords));
glintInfo->regs.OutFIFOWordsOdd =
TRANSLATE_ADDR(&(pCtrlRegsOdd->OutFIFOWords));
glintInfo->regs.DMAAddress =
TRANSLATE_ADDR(&(pCtrlRegs->DMAAddress));
glintInfo->regs.DMACount =
TRANSLATE_ADDR(&(pCtrlRegs->DMACount));
glintInfo->regs.InFIFOInterface =
TRANSLATE_ADDR(&(pCtrlRegs->FIFOInterface));
glintInfo->regs.OutFIFOInterface =
TRANSLATE_ADDR(&(pCtrlRegs->FIFOInterface));
glintInfo->regs.OutFIFOInterfaceOdd =
TRANSLATE_ADDR(&(pCtrlRegsOdd->FIFOInterface));
glintInfo->regs.IntFlags =
TRANSLATE_ADDR(&(pCtrlRegs->IntFlags));
glintInfo->regs.IntEnable =
TRANSLATE_ADDR(&(pCtrlRegs->IntEnable));
glintInfo->regs.ResetStatus =
TRANSLATE_ADDR(&(pCtrlRegs->ResetStatus));
glintInfo->regs.ErrorFlags =
TRANSLATE_ADDR(&(pCtrlRegs->ErrorFlags));
glintInfo->regs.DeltaIntFlags =
TRANSLATE_ADDR(&(pCtrlRegs->DeltaIntFlags));
glintInfo->regs.DeltaIntEnable =
TRANSLATE_ADDR(&(pCtrlRegs->DeltaIntEnable));
glintInfo->regs.DeltaErrorFlags =
TRANSLATE_ADDR(&(pCtrlRegs->DeltaErrorFlags));
glintInfo->regs.ScreenBase =
TRANSLATE_ADDR(&(pCtrlRegsVTG->ScreenBase));
glintInfo->regs.ScreenBaseRight =
TRANSLATE_ADDR(&(pCtrlRegsVTG->ScreenBaseRight));
glintInfo->regs.LineCount =
TRANSLATE_ADDR(&(pCtrlRegsVTG->LineCount));
glintInfo->regs.VbEnd =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VbEnd));
glintInfo->regs.VideoControl =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VideoControl));
glintInfo->regs.MemControl =
TRANSLATE_ADDR(&(pCtrlRegsVTG->MemControl));
glintInfo->regs.VTGSerialClk =
TRANSLATE_ADDR(&(pCtrlRegs->VTGSerialClk));
glintInfo->regs.VTGSerialClkOdd =
TRANSLATE_ADDR(&(pCtrlRegsOdd->VTGSerialClk));
glintInfo->regs.VClkCtl =
TRANSLATE_ADDR(&(pCtrlRegsVTG->VClkCtl));
glintInfo->regs.RacerDoubleWrite =
TRANSLATE_ADDR(&(pCtrlRegsVTG->RacerDoubleWrite));
glintInfo->regs.RacerBankSelect =
TRANSLATE_ADDR(&(pCtrlRegsVTG->RacerBankSelect));
//@@BEGIN_DDKSPLIT
// TMM: Add support for Omnicomp 3Demon Pro16
//@@END_DDKSPLIT
glintInfo->regs.DemonProDWAndStatus =
TRANSLATE_ADDR(&(pCtrlRegsVTG->DemonProDWAndStatus));
glintInfo->regs.DemonProUBufB =
TRANSLATE_ADDR(&(pCtrlRegsVTG->DemonProUBufB));
glintInfo->regs.DisconnectControl =
TRANSLATE_ADDR(&(pCtrlRegs->DisconnectControl));
// The following regs are P2 only - but it should be safe to calculate them for
// any chipset
glintInfo->regs.OutDMAAddress =
TRANSLATE_ADDR(&(pCtrlRegs->OutDMAAddress));
glintInfo->regs.OutDMACount =
TRANSLATE_ADDR(&(pCtrlRegs->OutDMACount));
glintInfo->regs.DMAControl =
TRANSLATE_ADDR(&(pCtrlRegs->DMAControl));
glintInfo->regs.AGPControl =
TRANSLATE_ADDR(&(pCtrlRegs->AGPControl));
glintInfo->regs.ByDMAAddress =
TRANSLATE_ADDR(&(pCtrlRegs->ByDMAAddress));
glintInfo->regs.ByDMAStride =
TRANSLATE_ADDR(&(pCtrlRegs->ByDMAStride));
glintInfo->regs.ByDMAMemAddr =
TRANSLATE_ADDR(&(pCtrlRegs->ByDMAMemAddr));
glintInfo->regs.ByDMASize =
TRANSLATE_ADDR(&(pCtrlRegs->ByDMASize));
glintInfo->regs.ByDMAByteMask =
TRANSLATE_ADDR(&(pCtrlRegs->ByDMAByteMask));
glintInfo->regs.ByDMAControl =
TRANSLATE_ADDR(&(pCtrlRegs->ByDMAControl));
glintInfo->regs.ByDMAComplete =
TRANSLATE_ADDR(&(pCtrlRegs->ByDMAComplete));
glintInfo->regs.VSConfiguration =
TRANSLATE_ADDR(&(pCtrlRegs->VSConfiguration));
glintInfo->regs.TextureDownloadControl =
TRANSLATE_ADDR(&(pCtrlRegs->TextureDownloadControl));
glintInfo->regs.LocalMemCaps =
TRANSLATE_ADDR(&(pCtrlRegs->LocalMemCaps));
glintInfo->regs.MemScratch =
TRANSLATE_ADDR(&(pCtrlRegs->MemScratch));
// The following regs are Gamma only - but it should be safe to calculate them for
// any chipset
glintInfo->regs.GammaCommandMode =
TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandMode));
glintInfo->regs.GammaCommandIntEnable =
TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandIntEnable));
glintInfo->regs.GammaCommandIntFlags =
TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandIntFlags));
glintInfo->regs.GammaCommandErrorFlags =
TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandErrorFlags));
glintInfo->regs.GammaCommandStatus =
TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandStatus));
glintInfo->regs.GammaFeedbackSelectCount =
TRANSLATE_ADDR(&(pCtrlRegs->GammaFeedbackSelectCount));
glintInfo->regs.GammaProcessorMode =
TRANSLATE_ADDR(&(pCtrlRegs->GammaProcessorMode));
glintInfo->regs.GammaChipConfig =
TRANSLATE_ADDR(&(pCtrlRegs->GammaChipConfig));
glintInfo->regs.GammaMultiGLINTAperture =
TRANSLATE_ADDR(&(pCtrlRegs->GammaMultiGLINTAperture));
// PXRX only bypass stuff:
glintInfo->regs.PXRXByAperture1Mode = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByAperture1Mode) );
glintInfo->regs.PXRXByAperture1Stride = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByAperture1Stride) );
//glintInfo->regs.PXRXByAperture1YStart
//glintInfo->regs.PXRXByAperture1UStart
//glintInfo->regs.PXRXByAperture1VStart
glintInfo->regs.PXRXByAperture2Mode = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByAperture2Mode) );
glintInfo->regs.PXRXByAperture2Stride = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByAperture2Stride) );
//glintInfo->regs.PXRXByAperture2YStart
//glintInfo->regs.PXRXByAperture2UStart
//glintInfo->regs.PXRXByAperture2VStart
glintInfo->regs.PXRXByDMAReadMode = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByDMAReadMode) );
glintInfo->regs.PXRXByDMAReadStride = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByDMAReadStride) );
//glintInfo->regs.PXRXByDMAReadYStart
//glintInfo->regs.PXRXByDMAReadUStart
//glintInfo->regs.PXRXByDMAReadVStart
glintInfo->regs.PXRXByDMAReadCommandBase = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByDMAReadCommandBase) );
glintInfo->regs.PXRXByDMAReadCommandCount = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByDMAReadCommandCount) );
//glintInfo->regs.PXRXByDMAWriteMode
//glintInfo->regs.PXRXByDMAWriteStride
//glintInfo->regs.PXRXByDMAWriteYStart
//glintInfo->regs.PXRXByDMAWriteUStart
//glintInfo->regs.PXRXByDMAWriteVStart
//glintInfo->regs.PXRXByDMAWriteCommandBase
//glintInfo->regs.PXRXByDMAWriteCommandCount
// Debug/profile registers on a P3.
glintInfo->regs.TestOutputRdy = TRANSLATE_ADDR( &(pCtrlRegs->TestOutputRdy) );
glintInfo->regs.TestInputRdy = TRANSLATE_ADDR( &(pCtrlRegs->TestInputRdy) );
glintInfo->regs.LocalMemProfileMask0 = TRANSLATE_ADDR( &(pCtrlRegs->LocalMemProfileMask0) );
glintInfo->regs.LocalMemProfileMask1 = TRANSLATE_ADDR( &(pCtrlRegs->LocalMemProfileMask1) );
glintInfo->regs.LocalMemProfileCount0 = TRANSLATE_ADDR( &(pCtrlRegs->LocalMemProfileCount0) );
glintInfo->regs.LocalMemProfileCount1 = TRANSLATE_ADDR( &(pCtrlRegs->BootAddress) );
// initialize the overlay to be disabled
glintInfo->OverlayMode = GLINT_DISABLE_OVERLAY;
glintInfo->WriteMask = 0xffffffff;
glintInfo->DefaultWriteMask = 0xffffffff;
//@@BEGIN_DDKSPLIT
// TMM: On ELSA Gloria Gamma boards with 640 RAMDACs at 15BPP, bit 15 is used
// by the RAMDAC to select a different LUT. So we have to mask
// the top bit out when writing to the framebuffer.
//@@END_DDKSPLIT
if (glintInfo->deviceInfo.ActualDacId == RGB640_RAMDAC &&
ppdev->cPelSize == GLINTDEPTH16)
{
glintInfo->DefaultWriteMask = 0x7FFF7FFF;
glintInfo->WriteMask = 0x7FFF7FFF;
}
// Initialise current FIFO count
glintInfo->FifoCnt = 0;
//@@BEGIN_DDKSPLIT
#if 0 // HIDEYUKN
//
// If we have a gamma ramp saved in the registry then use that. Otherwise,
// initialize the LUT with a gamma of 1.0
//
if (!bGlintRegistryRetrieveGammaLUT(ppdev, &glintInfo->gammaLUT) ||
!bInstallGammaLUT(ppdev, &glintInfo->gammaLUT, FALSE))
{
vSetNewGammaValue(ppdev, 0x10000, FALSE);
}
#endif
//@@END_DDKSPLIT
//
// initialize our DMA buffers if any are configured
//
vGlintInitializeDMA(ppdev);
// fill in the glintInfo capability flags and block fill size.
//
glintInfo->flags |= GLICAP_NT_CONFORMANT_LINES;
glintInfo->fastFillSupport = 0;
glintInfo->renderFastFill = 0;
glintInfo->fastFillBlockSz = 0;
{
ULONG DMAMemoryControl = 0;
DMAMemoryControl |= 1 << 2; // align host-in DMA to 64 bit boundaries
DMAMemoryControl |= (0 & 0x1f) << 24; // burst size n == (1 << 7+n)? Spec indicates n * 128
DMAMemoryControl |= 1 << 31; // align host-out DMA to 64 bit boundaries
if( ppdev->flCaps & CAPS_USE_AGP_DMA )
DMAMemoryControl |= 1 << 0; // host-in DMA uses AGP
WAIT_GLINT_FIFO(1);
LD_GLINT_FIFO(__GlintTagDMAMemoryControl, DMAMemoryControl);
}
{
ULONG *dmaVirt = glintInfo->PXRXDMABuffer.virtAddr;
ULONG dmaPhys = (ULONG) glintInfo->PXRXDMABuffer.physAddr.LowPart;
ULONG size = (glintInfo->PXRXDMABuffer.size) / sizeof(ULONG);
DISPDBG((DBGLVL, "PXRX_DMA: allocated: 0x%08X + 0x%08X @ 0x%08X",
glintInfo->PXRXDMABuffer.virtAddr, glintInfo->PXRXDMABuffer.size, glintInfo->PXRXDMABuffer.physAddr));
if ((glintInfo->PXRXDMABuffer.virtAddr == 0) ||
(glintInfo->PXRXDMABuffer.size == 0 ) ||
(glintInfo->PXRXDMABuffer.physAddr.LowPart == 0))
{
DISPDBG((DBGLVL, "PXRX_DMA: Physical buffer allocation has failed, using a virtual buffer..."));
size = 256 * 1024;
dmaVirt = (ULONG *) ENGALLOCMEM(FL_ZERO_MEMORY,
size * sizeof(ULONG),
ALLOC_TAG_GDI(B));
if (NULL == dmaVirt)
{
DISPDBG((-1, "FATAL ERROR: DRIVER REQUIRES DMA BUFFER FOR 2D - UNLOADING DRIVER"));
return(FALSE);
}
glintInfo->PXRXDMABuffer.size = size;
glintInfo->PXRXDMABuffer.virtAddr = dmaVirt;
glintInfo->PXRXDMABuffer.physAddr.LowPart = 0;
glintInfo->PXRXDMABuffer.physAddr.HighPart = 0;
glintInfo->usePXRXdma = USE_PXRX_DMA_FIFO;
pxrxSetupFunctionPointers( ppdev );
}
ASSERTDD( glintInfo->PXRXDMABuffer.virtAddr != 0, "PXRX_DMA: The buffer has no virtual address!" );
ASSERTDD( glintInfo->PXRXDMABuffer.size != 0, "PXRX_DMA: The buffer has a zero size!" );
# if PXRX_DMA_BUFFER_CHECK
{
ULONG protSize = PXRX_DMA_BUFFER_CHECK_SIZE;
ULONG buffSize = (size - (protSize * 3)) / 2;
ULONG *ptr;
/*
0k - 16k = 16k = protection zone 0
16k - 56k = (size - (16 * 3)) / 2 = buffer 0
56k - 72k = 16k = protection zone 1
72k - 112k = (size - (16 * 3)) / 2 = buffer 1
112k - 128k = 16k = protection zone 2
*/
glintInfo->pxrxDMA_bufferBase = dmaVirt;
glintInfo->pxrxDMA_bufferTop = &dmaVirt[size];
gi_pxrxDMA.DMAaddrL[0] = &dmaVirt[protSize];
gi_pxrxDMA.DMAaddrEndL[0] = gi_pxrxDMA.DMAaddrL[0] + buffSize;
gi_pxrxDMA.DMAaddrL[1] = gi_pxrxDMA.DMAaddrEndL[0] + protSize;
gi_pxrxDMA.DMAaddrEndL[1] = gi_pxrxDMA.DMAaddrL[1] + buffSize;
for( ptr = dmaVirt; ptr < glintInfo->pxrxDMA_bufferTop; ptr++ )
*ptr = (ULONG)(((ULONG_PTR) ptr) & 0x0FFFFFF0);
DISPDBG((DBGLVL, "PXRX_DMA: prot 0 = 0x%08X -> 0x%08X", glintInfo->pxrxDMA_bufferBase, gi_pxrxDMA.DMAaddrL[0]));
DISPDBG((DBGLVL, "PXRX_DMA: buffer 0 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrL[0], gi_pxrxDMA.DMAaddrEndL[0]));
DISPDBG((DBGLVL, "PXRX_DMA: prot 1 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrEndL[0], gi_pxrxDMA.DMAaddrL[1]));
DISPDBG((DBGLVL, "PXRX_DMA: buffer 1 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrL[1], gi_pxrxDMA.DMAaddrEndL[1]));
DISPDBG((DBGLVL, "PXRX_DMA: prot 2 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrEndL[1], glintInfo->pxrxDMA_bufferTop));
}
# else // PXRX_DMA_BUFFER_CHECK
gi_pxrxDMA.DMAaddrL[0] = dmaVirt;
gi_pxrxDMA.DMAaddrL[1] = &dmaVirt[ size / 2 ];
gi_pxrxDMA.DMAaddrEndL[0] = &dmaVirt[(size / 2) - 1];
gi_pxrxDMA.DMAaddrEndL[1] = &dmaVirt[ size - 1];
# endif // PXRX_DMA_BUFFER_CHECK
gi_pxrxDMA.NTbuff = 0;
gi_pxrxDMA.NTptr = gi_pxrxDMA.DMAaddrL[gi_pxrxDMA.NTbuff];
gi_pxrxDMA.NTdone = gi_pxrxDMA.NTptr;
gi_pxrxDMA.P3at = gi_pxrxDMA.NTptr;
#if PXRX_DMA_BUFFER_CHECK
glintInfo->NTwait = gi_pxrxDMA.NTptr;
#endif
gi_pxrxDMA.DMAaddrP[0] = dmaPhys + (DWORD)((UINT_PTR) gi_pxrxDMA.DMAaddrL[0] - (UINT_PTR) dmaVirt);
gi_pxrxDMA.DMAaddrP[1] = dmaPhys + (DWORD)((UINT_PTR) gi_pxrxDMA.DMAaddrL[1] - (UINT_PTR) dmaVirt);
gi_pxrxDMA.DMAaddrEndP[0] = dmaPhys + (DWORD)((UINT_PTR) gi_pxrxDMA.DMAaddrEndL[0] - (UINT_PTR) dmaVirt);
gi_pxrxDMA.DMAaddrEndP[1] = dmaPhys + (DWORD)((UINT_PTR) gi_pxrxDMA.DMAaddrEndL[1] - (UINT_PTR) dmaVirt);
DISPDBG((DBGLVL, "PXRX_DMA: buffer 0 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrL[0], gi_pxrxDMA.DMAaddrEndL[0]));
DISPDBG((DBGLVL, "PXRX_DMA: buffer 1 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrL[1], gi_pxrxDMA.DMAaddrEndL[1]));
#if PXRX_DMA_BUFFER_CHECK
{
extern ULONG inPxRxContextSwitch;
inPxRxContextSwitch = TRUE;
CHECK_PXRX_DMA_VALIDITY( CHECK_SWITCH, 0 );
inPxRxContextSwitch = FALSE;
}
#endif
}
// Allocate a GLINT context for this PDEV. Save the current context
// if any and make us the current one but do this by hand since our
// software copy will be junk if this is the very first PDEV.
//
DISPDBG((DBGLVL, "allocating new context"));
// Create the 2D context:
glintInfo->ddCtxtId = GlintAllocateNewContext(ppdev,
(ULONG *) pxrxRestore2DContext,
0, 0, NULL, ContextType_Fixed);
if (glintInfo->ddCtxtId < 0)
{
DISPDBG((ERRLVL, "failed to allocate GLINT context for display driver"));
return(FALSE);
}
DISPDBG((DBGLVL, "got context id 0x%x", glintInfo->ddCtxtId));
GLINT_VALIDATE_CONTEXT(-1);
ppdev->currentCtxt = glintInfo->ddCtxtId;
DISPDBG((DBGLVL, "context id 0x%x is now current", glintInfo->ddCtxtId));
if (ppdev->flCaps & CAPS_QUEUED_DMA)
{
DISPDBG((DBGLVL, "Enabling queued DMA for Gamma - initializing control regs"));
READ_GLINT_CTRL_REG(GammaCommandMode, ulValue);
ulValue |= GAMMA_COMMAND_MODE_QUEUED_DMA;
WRITE_GLINT_CTRL_REG(GammaCommandMode, ulValue);
}
if( GLINT_GAMMA_PRESENT )
{
//
// The disconnect should be setup correctly in the miniport.
//
glintInfo->PCIDiscEnabled = FALSE;
} else {
// Configure PCI disconnect
//
if (ppdev->cPelSize == GLINTDEPTH32)
{
glintInfo->PCIDiscEnabled = FALSE;
}
else
{
glintInfo->PCIDiscEnabled = USE_PCI_DISC_PERM;
}
// Enable/Disable PCI disconnect as required
WRITE_GLINT_CTRL_REG(DisconnectControl,
(glintInfo->PCIDiscEnabled ? DISCONNECT_INPUT_FIFO_ENABLE :
DISCONNECT_INOUT_DISABLE));
}
// We only want to check the FIFO if disconnect is disabled.
glintInfo->CheckFIFO = !glintInfo->PCIDiscEnabled;
// Setup DMA control on GMX or PXRX
{
ULONG DMAControl = DMA_CONTROL_USE_PCI;
if (!(ppdev->flCaps & CAPS_USE_AGP_DMA))
{
DMAControl = DMA_CONTROL_USE_PCI; // AGP not enabled use PCI master DMA
}
else
{
DMAControl = 2; // PXRX: use AGP master DMA
// When using AGP SideBandAddressing, the following tweak should be a performance gain
WRITE_GLINT_CTRL_REG (AGPControl, AGP_LONG_READ_DISABLE );
}
// Write DMA control
WRITE_GLINT_CTRL_REG (DMAControl, DMAControl);
}
// there are many mode registers we never use so we must disable them.
//
vInitCoreRegisters(ppdev);
ulValue = 32;
DISPDBG((DBGLVL, "Using block fill of width %d pixels", ulValue));
glintInfo->fastFillBlockSz = ulValue;
glintInfo->fastFillSupport = __RENDER_FAST_FILL_INC(ulValue);
glintInfo->renderFastFill = __RENDER_FAST_FILL_ENABLE |
__RENDER_FAST_FILL_INC(ulValue);
// On a Geo Twin we disable the pointer cache and brush cache.
// and on a delta-based Geo Twin we disable off-screen bitmaps too,
// because they slow things down.
if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
{
// Gamma boards can have off-screen bitmaps, because Gamma has
// something called the multi-glint aperture.
if (GLINT_DELTA_PRESENT)
ppdev->flStatus &= ~(STAT_DEV_BITMAPS | ENABLE_DEV_BITMAPS);
//@@BEGIN_DDKSPLIT
// ppdev->flStatus &= ~(ENABLE_POINTER_CACHE);
// ppdev->flStatus &= ~(ENABLE_BRUSH_CACHE);
// ppdev->flStatus &= ~(ENABLE_GLYPH_CACHE);
//@@END_DDKSPLIT
}
// initially assume that we do not have an off-screen buffer for
// bitblt and full screen double buffering. So set all buffer offsets
// to zero. This may get overriden when we init the off-screen heap.
//
for (i = 0; i < GLINT_NUM_SCREEN_BUFFERS; ++i)
{
glintInfo->bufferOffset[i] = 0;
glintInfo->bufferRow[i] = 0;
}
// Initialise back-buffer POH
glintInfo->backBufferPoh = NULL;
glintInfo->GMX2KLastLine = 0;
// Work out our double buffering requirements. First read the registry to
// find out if we need an off-screen buffer. If not then we have nothing
// to do. We want an off-screen buffer if the string exists and the
// buffer count is >= 2. For the moment values > 2 mean use two buffers.
// i.e. we don't support triple or quad buffering etc.
// Note, for GLINT we assume that the extra buffer always lives
// below the visible buffer (i.e. not to the right).
// If the variable doesn't exist, assume 2 buffers.
//
bCreateBackBuffer = FALSE;
bCreateStereoBuffers = FALSE;
bExists = bGlintQueryRegistryValueUlong(ppdev,
REG_NUMBER_OF_SCREEN_BUFFERS,
&ulValue);
if (!bExists)
{
ulValue = 2;
}
if ((ulValue >= 2) && (ppdev->cyMemory >= (ppdev->cyScreen << 1)))
{
//@@BEGIN_DDKSPLIT
//ULONG ulValue;
LONG leftOffset;
LONG byteTotal;
LONG lTotal;
ULONG rowSz;
// if (GLINT_PXRX) // ???
if (1)
{
#if 0
// if we have enough SGRAM then we can support both BLT and
// full screen double buffering.
glintInfo->flags |= GLICAP_BITBLT_DBL_BUF |
GLICAP_FULL_SCREEN_DBL_BUF;
cx = ppdev->cxMemory;
cy = ppdev->cyScreen;
lTotal = cx * cy;
rowSz = 1;
leftOffset = 0;
#else
//@@END_DDKSPLIT
bCreateBackBuffer = TRUE;
//@@BEGIN_DDKSPLIT
goto ConfigurePermediaBuffers;
#endif
}
else
{
// we have enough VRAM so we at least support BLT double buffering
glintInfo->flags |= GLICAP_BITBLT_DBL_BUF;
// read FBModeSel to get the interleave etc. We're only interested in
// whether we are up to 2-way or 4-way, so the left shift is adequate.
// i.e. I don't care that (0 << 1) is "zero-way" rather than 1-way.
//
cx = ppdev->cxMemory;
cy = ppdev->cyScreen;
lTotal = cx * cy;
//@@BEGIN_DDKSPLIT
// AZN This code was originally not being used
#if 0
if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
{
OH *pohTmp;
ULONG NumpadLines;
LONG halfWay = ppdev->FrameBufferLength >> 1; // TMM: This was FOUR_MB
NumpadLines = ((halfWay / ppdev->lDelta) - ppdev->cyScreen; & ~1;
DISPDBG((DBGLVL, "Allocating padding bitmap of size %d x %d",
cx, NumpadLines));
pohTmp = pohAllocate(ppdev, NULL, cx, NumpadLines, 0);
ASSERTDD(pohTmp != NULL, "pad buffer could not be allocated");
// now allocate the actual back buffer
cy = ((((halfWay + ppdev->lDelta - 1) / ppdev->lDelta) - NumpadLines) + 1) & ~1;
DISPDBG((DBGLVL, "Allocating Racer back buffer of size %d x %d", cx, cy));
poh = pohAllocate(ppdev, NULL, cx, cy, FLOH_MAKE_PERMANENT);
ASSERTDD((poh != NULL) && (poh->x == 0) && (poh->y == (halfWay / ppdev->lDelta)),
"Racer off-screen buffer allocated in incorrect position");
DISPDBG((DBGLVL, "Racer back buffer at %d, %d", poh->x, poh->y));
// as far as the 3D ext is concerned, the buffer lives at the
// pixel address of the half-way boundary, but the VTGFrameRowAddr
// is zero. We will examine the (GLICAP_RACER_BANK_SELECT |
// GLICAP_ENHANCED_TX_BANK_SELECT) bits at swap time to see which
// register we should load.
//
glintInfo->bufferOffset[1] = halfWay >> ppdev->cPelSize;
glintInfo->bufferRow[1] = 0;
DISPDBG((DBGLVL, "Racer offscreen buffer at offset 0x%x", GLINT_BUFFER_OFFSET(1)));
// release the temporary buffer. We can use this as off-screen
// memory.
pohFree(ppdev, pohTmp);
}
#endif
//@@END_DDKSPLIT
// now see if we can handle full screen double buffering. This has
// a slightly more stringent requirement because the second buffer
// must start on a VRAM RAS line. OK, here's the equation for the
// number of pixels per RAS line:
// 512 * interleave_size * width_in_dwords * pixels_per_dword
// The only dodgy number here is 512 but I am assured that all
// the VRAMs that GLINT supports have this shift register size.
//
READ_GLINT_CTRL_REG (FBModeSel, ulValue);
DISPDBG((DBGLVL, "FBModeSel = 0x%x", ulValue));
rowSz = 512 << ((ulValue & 1) + // width in dwords
((ulValue >> 8) & 3) + // interleave value
(2 - ppdev->cPelSize)); // pixels per dword
DISPDBG((DBGLVL, "got FrameRow of size 0x%x pixels", rowSz));
// we have the RAS line size, so we must ensure that the second
// buffer starts at a multiple of this many pixels from the
// origin. This may not be zero in x since the screen stride may
// not be a multiple of this number. So we calculate the number
// of extra scanlines we need to span a full buffer that starts
// on a RAS line boundary. Note, we know that rowSz is a
// power of 2 so we can subtract 1 to get a mod mask.
//
leftOffset = (ULONG)(-lTotal) & (rowSz - 1);
cy += (leftOffset + (cx-1)) / cx;
// cx and cy are now the dimensions of the off-screen buffer we
// want, including the extra scanlines needed to align the full
// screen buffer. Since cy may have increased, again check we
// have enough VRAM. If not then the full-screen alignment will
// have caused us to run over the end. In this case we can position
// the off-screen buffer immediately after the screen but we can't
// offset into it the number of pixels required to align a
// full-screen double buffer.
//
if ((ppdev->cyScreen + cy) <= ppdev->cyMemory)
{
// We can use VTGRowAddress if:
// we don't cross a 4MB boundary or
// (we have an interleave factor of 4 and we don't have an Omnicomp 3Demon Pro16)
// else we can use Racer bank select if we have a Racer board.
//
if ((glintInfo->deviceInfo.BoardId == GLINT_RACER) ||
(glintInfo->deviceInfo.BoardId == GLINT_RACER_PRO) ||
(glintInfo->deviceInfo.BoardId == OMNICOMP_3DEMONPRO) ||
(glintInfo->deviceInfo.BoardId == GEO_TWIN_BOARD) ||
(glintInfo->deviceInfo.BoardId == ACCELPRO_BOARD) ||
(glintInfo->deviceInfo.BoardId == ELSA_GLORIA_XL) ||
(glintInfo->deviceInfo.BoardId == ELSA_GLORIA))
{
glintInfo->flags |= GLICAP_FULL_SCREEN_DBL_BUF |
GLICAP_RACER_DOUBLE_WRITE;
// The 3Demon Pro16 board does not support, enhanced
// mode bank-switching.
if ((ppdev->flCaps & CAPS_ENHANCED_TX) &&
(!IS_RACER_VARIANT_PRO16(ppdev)))
{
DISPDBG((DBGLVL, "Enhanced TX full-screen buffering"));
glintInfo->flags |= GLICAP_ENHANCED_TX_BANK_SELECT;
}
else
{
DISPDBG((DBGLVL, "Racer bank select full-screen buffering"));
glintInfo->flags |= GLICAP_RACER_BANK_SELECT;
}
}
else if (((ppdev->cyScreen + cy) * ppdev->lDelta <= FOUR_MB) ||
((!IS_RACER_VARIANT_PRO16(ppdev))))
{
DISPDBG((DBGLVL, "VTGFrameRowAddress full-screen buffering"));
glintInfo->flags |= GLICAP_FULL_SCREEN_DBL_BUF;
}
}
else
cy = ppdev->cyScreen;
}
if (glintInfo->flags & (GLICAP_RACER_BANK_SELECT |
GLICAP_ENHANCED_TX_BANK_SELECT))
{
// The second buffer must start in the second half of the frame
// buffer (i.e. at 4MB for an 8MB card and 8MB for a 16MB card) so
// allocate enough off-screen heap to pad up to the scanline
// before this boundary. Then we allocate enough lines so that
// we can move the buffer start to 4MB.
//
OH *pohTmp;
ULONG padLines;
LONG halfWay = ppdev->FrameBufferLength >> 1; // This was FOUR_MB
LONG lScreenDelta;
lScreenDelta = ppdev->lDelta;
padLines = (halfWay / lScreenDelta) - ppdev->cyScreen;
if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
padLines &= ~1; // make number of pad lines even
DISPDBG((DBGLVL, "Allocating padding bitmap of size %d x %d", ppdev->cxScreen, padLines));
pohTmp = pohAllocate(ppdev, NULL, ppdev->cxScreen, padLines, 0);
ASSERTDD(pohTmp != NULL, "pad buffer could not be allocated");
DISPDBG((DBGLVL, "Racer padding bitmap at %d, %d", pohTmp->x, pohTmp->y));
// now allocate the actual back buffer
cy = ((halfWay + lScreenDelta - 1) / lScreenDelta) - padLines;
if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
cy = (cy + 1) & ~1; // round up to make even
DISPDBG((DBGLVL, "Allocating Racer back buffer of size %d x %d", ppdev->cxScreen, cy));
poh = pohAllocate(ppdev, NULL, ppdev->cxScreen, cy, FLOH_MAKE_PERMANENT);
if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER) {
ASSERTDD((poh != NULL) && (poh->x == 0) && (poh->y <= (halfWay / lScreenDelta)) && (poh->y >= ((halfWay / lScreenDelta) - 1)),
"Racer back buffer allocated in incorrect position");
} else {
ASSERTDD((poh != NULL) && (poh->x == 0) && (poh->y == (halfWay / lScreenDelta)),
"Racer back buffer allocated in incorrect position");
}
DISPDBG((DBGLVL, "Racer back buffer at %d, %d", poh->x, poh->y));
// as far as the 3D ext is concerned, the buffer lives at the
// pixel address of the half-way boundary, but the VTGFrameRowAddr
// is zero. We will examine the (GLICAP_RACER_BANK_SELECT |
// GLICAP_ENHANCED_TX_BANK_SELECT) bits at swap time to see which
// register we should load.
//
glintInfo->bufferOffset[1] = halfWay >> ppdev->cPelSize;
if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
glintInfo->bufferOffset[1] >>= 1;
glintInfo->bufferRow[1] = 0;
DISPDBG((DBGLVL, "Racer offscreen buffer at offset 0x%x", GLINT_BUFFER_OFFSET(1)));
// Save the back-buffer POH
glintInfo->backBufferPoh = poh;
// release the temporary buffer. We can use this as off-screen
// memory.
pohFree(ppdev, pohTmp);
if (cy > ppdev->cyScreen)
{
POINTL ptl;
OH * pohtmptmp;
LONG lpadLines;
// Calculate padding, ensuring on a Geo we always allocate an
// even number
lpadLines = (cy - ppdev->cyScreen) + 1;
if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER && (lpadLines & 0x1))
lpadLines++;
ptl.x = 0; // Allocate strip directly after the front buffer
ptl.y = ppdev->cyScreen;
pohtmptmp = pohAllocate (ppdev, &ptl, ppdev->cxScreen, lpadLines, FLOH_MAKE_PERMANENT);
ASSERTDD (pohtmptmp, "16BPP Pad buffer alloc failed");
}
}
else
{
// Allocate the off-screen buffer. When we get it back, its
// position should be immediately below the visible screen.
// Since we have checked that we have enough VRAM and GLINT
// never has off-screen memory to the right, it will fail only
// if we get our logic mixed up. e.g. if the initialization
// routines were re-ordered so that the brush cache got called
// before this routine.
//
poh = pohAllocate(ppdev, NULL, cx, cy, FLOH_MAKE_PERMANENT);
ASSERTDD((poh != NULL) && (poh->x == 0) && (poh->y == ppdev->cyScreen),
"off-screen buffer allocated in incorrect position");
DISPDBG((DBGLVL, "allocated off-screen buffer at (%d,%d), w %d h %d",
poh->x, poh->y, poh->cx, poh->cy));
glintInfo->bufferOffset[1] = lTotal;
if (GLINT_FS_DBL_BUF)
{
glintInfo->bufferOffset[1] += leftOffset;
glintInfo->bufferRow[1] = (lTotal + leftOffset) / rowSz;
ASSERTDD(GLINT_BUFFER_OFFSET(1)%rowSz == 0, "off-screen buffer origin not on RAS line");
}
else
leftOffset = 0;
DISPDBG((DBGLVL, "offscreen buffer at offset 0x%x", GLINT_BUFFER_OFFSET(1)));
}
#ifdef LATER
// We want to create a DIB and surface for the off-screen bitmap.
// However, the bitmap must start at the correct origin. i.e. if
// we had to offset the origin to match the VRAM page size (for
// full screen double buffering) we must move the origin in the
// poh. Since the node is allocated permanently we don't have to
// worry about changing poh->x and poh->y. Famous last words?
//
if (leftOffset > 0)
{
poh->x += leftOffset % ppdev->cxMemory;
poh->y += leftOffset / ppdev->cxMemory;
}
// allocate our DSURF object for the off-screen buffer.
//
pdsurf = ENGALLOCMEM(FL_ZERO_MEMORY,
sizeof(DSURF),
ALLOC_TAG_GDI(C));
if (pdsurf == NULL)
{
DISPDBG((ERRLVL, "bInitializeGlint - Failed pdsurf allocation"));
return(FALSE);
}
ppdev->pdsurfOffScreen = pdsurf; // Remember it for clean-up
pdsurf->poh = poh;
poh->pdsurf = pdsurf;
pdsurf->dt = DT_SCREEN;
pdsurf->bOffScreen = TRUE;
pdsurf->sizl.cx = ppdev->cxScreen; // the poh may be bigger but
pdsurf->sizl.cy = ppdev->cyScreen; // this is the valid size.
pdsurf->ppdev = ppdev;
if (!bCreateScreenDIBForOH(ppdev, poh, HOOK_SYNCHRONIZE))
{
DISPDBG((WRNLVL, "bCreateScreenDIBForOH failed for off-screen buffer"));
return(FALSE);
}
if(pdsurf->pso)
{
DISPDBG((DBGLVL, "pdsurf->pso for off-screen memory:"));
DISPDBG((DBGLVL, "DHSURF 0x%x", pdsurf->pso->dhsurf));
DISPDBG((DBGLVL, "HSURF 0x%x", pdsurf->pso->hsurf));
DISPDBG((DBGLVL, "DHPDEV 0x%x", pdsurf->pso->dhpdev));
DISPDBG((DBGLVL, "sizlBitmap %d, %d", pdsurf->pso->sizlBitmap.cx, pdsurf->pso->sizlBitmap.cy));
DISPDBG((DBGLVL, "cjBits 0x%x", pdsurf->pso->cjBits));
DISPDBG((DBGLVL, "pvBits 0x%x", pdsurf->pso->pvBits));
DISPDBG((DBGLVL, "pvScan0 0x%x", pdsurf->pso->pvScan0));
DISPDBG((DBGLVL, "lDelta %d", pdsurf->pso->lDelta));
DISPDBG((DBGLVL, "iBitmapFormat 0x%x", pdsurf->pso->iBitmapFormat));
DISPDBG((DBGLVL, "iType 0x%x", pdsurf->pso->iType));
DISPDBG((DBGLVL, "fjBitmap 0x%x", pdsurf->pso->fjBitmap));
}
#endif // LATER
//@@END_DDKSPLIT
}
//@@BEGIN_DDKSPLIT
ConfigurePermediaBuffers:
//@@END_DDKSPLIT
// Work out the position and sizes for Z buffer and texture memory.
// For PERMEDIA we need to reserve these with the heap manager since we
// have a unified memory. For the moment, we will use all the available
// extra memory for textures. Maybe later make it configurable to allow
// the 2D driver some off-screen memory.
// NB. P2 allocates a font cache here, it may be preferable to use the
// registry to determine the size of the cache
LOCALBUFFER_PIXEL_WIDTH = 0; // bits
LOCALBUFFER_PIXEL_OFFSET = 0; // Z pels
LOCALBUFFER_PIXEL_COUNT = 0; // Z pels
FONT_MEMORY_OFFSET = 0; // dwords
FONT_MEMORY_SIZE = 0; // dwords
TEXTURE_MEMORY_OFFSET = 0; // dwords
TEXTURE_MEMORY_SIZE = 0; // dwords
{
ULONG cjGlyphCache;
LONG LBPelSize, PatchWidth, PatchRemainder, ZScreenWidth;
ULONG cyPermanentCaches, cyGlyphCache, cyPointerCache;
LONG yOrg, ZHeight;
cjGlyphCache = 300 * 1024;
//@@BEGIN_DDKSPLIT
#if 0
// we don't have a brush cache for these chips
ppdev->flStatus &= ~ENABLE_BRUSH_CACHE;
#endif
//@@END_DDKSPLIT
// 3D extension fails if we have no textures or Z buffer but still
// operates without a back buffer. So if we don't have enough
// memory for Z or textures then abort buffer configuration.
// (if width=16 => pelsize=1,patchwidth=128)
LOCALBUFFER_PIXEL_WIDTH = 32;
LBPelSize = 2;
PatchWidth = 64;
DISPDBG((DBGLVL, "bInitializeGlint: P3 Localbuffer width set to %i", LOCALBUFFER_PIXEL_WIDTH ));
if (ppdev->cPelSize >= LBPelSize)
{
ZHeight = ppdev->cyScreen >> (ppdev->cPelSize - LBPelSize);
}
else
{
ZHeight = ppdev->cyScreen << (LBPelSize - ppdev->cPelSize);
}
bCreateBackBuffer = TRUE;
// Decide if we want to allocate some stereo buffers.
if(ppdev->flCaps & CAPS_STEREO)
{
bCreateStereoBuffers = TRUE;
}
cy = ppdev->cyScreen; // front buffer height
cy += ZHeight; // add on Z buffer height
cy += TEXTURE_OH_MIN_HEIGHT; // minimum required texture memory
if (cy > ppdev->cyMemory)
{
// Start DirectDraw after the end of the screen
ppdev->heap.DDrawOffscreenStart = ppdev->cxMemory * ppdev->cyScreen;
DISPDBG((ERRLVL, "not enough memory for 3D buffers, dd: 0x%x\n", ppdev->heap.DDrawOffscreenStart));
goto CompletePermediaBuffers;
}
// is there room for a back buffer?
if ((cy + ppdev->cyScreen) > ppdev->cyMemory)
{
bCreateBackBuffer = FALSE;
}
else if (bCreateBackBuffer)
{
cy += ppdev->cyScreen;
}
// is there room for stereo buffers?
if ((cy + (2*ppdev->cyScreen)) > ppdev->cyMemory)
{
bCreateStereoBuffers = FALSE;
}
else if (bCreateStereoBuffers)
{
cy += (2*ppdev->cyScreen);
}
// cy is now the total length of all buffers required for 3D.
// cyPermanentCaches is the combined height of the 2D caches that lie between the front & back buffers
cyPermanentCaches = 0;
// yOrg is the start of offscreen memory
yOrg = ppdev->cyScreen + cyPermanentCaches;
if (bCreateBackBuffer)
{
glintInfo->flags |= GLICAP_BITBLT_DBL_BUF | GLICAP_FULL_SCREEN_DBL_BUF;
if (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK)
{
ULONG bb, patchWidth, patchSize, x, y;
/*
Align Size cPelSize 2 - cPS 4 - cPS
32bpp: 0x100 0x1000 2 0 >> 1 2 >> 4
16bpp: 0x 80 0x 800 1 1 >> 2 3 >> 8
8bpp: 0x 40 0x 400 0 2 >> 4 4 >> 16
patchSize = 0x400 << ppdev->cPelSize; // Bytes
regAlign = 0x40 << ppdev->cPelSize; // 128 bits
reg = bufferOffset >> (4 - ppdev->cPelSize);
bufferOffsetAlignment = regAlign << (4 - ppdev->cPelSize); // 1024
= (0x40 << ppdev->cPelSize) << (4 - ppdev->cPelSize);
= 0x40 << 4;
= 1024;
NB: verticalAlignment = 16 scanlines;
*/
bb = ((ppdev->cxMemory * yOrg) + 1023) & ~1023;
if( bb % ppdev->cxMemory )
bb = (bb / ppdev->cxMemory) + 1;
else
bb = bb / ppdev->cxMemory;
bb = (bb + 15) & ~15;
bb *= ppdev->cxMemory;
ppdev->heap.DDrawOffscreenStart = // Save DirectDraw off-screen offset
glintInfo->bufferRow[1] =
glintInfo->bufferOffset[1] = bb;
x = bb % ppdev->cxMemory;
y = bb / ppdev->cxMemory;
glintInfo->backBufferXY = (x & 0xFFFF) | (y << 16);
//LOAD_FBWRITE_OFFSET( 1, glintInfo->backBufferXY );
yOrg = y + ppdev->cyScreen; // Y origin of next buffer
}
else
{
ppdev->heap.DDrawOffscreenStart = // Save DirectDraw off-screen offset
glintInfo->bufferRow[1] =
glintInfo->bufferOffset[1] = ppdev->cxMemory * yOrg;
glintInfo->backBufferXY = yOrg << 16;
//LOAD_FBWRITE_OFFSET( 1, glintInfo->backBufferXY );
yOrg += ppdev->cyScreen; // Y origin of next buffer
}
DISPDBG((DBGLVL, "offscreen buffer at offset 0x%x", GLINT_BUFFER_OFFSET(1)));
}
else
{
// DirectDraw can use the memory that is left over
ppdev->heap.DDrawOffscreenStart = ppdev->cxMemory * yOrg;
DISPDBG((DBGLVL, "No Permedia back buffer being created dd: 0x%x", ppdev->heap.DDrawOffscreenStart));
}
// Setup stereo front and back buffers if they're required.
// We just place them directly after the back buffer.
// Patching requirements should be satisfied as long as the
// front and back are patched/unpatched together.
if (bCreateStereoBuffers)
{
// Stereo back buffer
glintInfo->backRightBufferXY = (glintInfo->backBufferXY + (ppdev->cyScreen << 16));
glintInfo->bufferRow[2] = glintInfo->bufferOffset[2] =
(glintInfo->bufferOffset[1] + (ppdev->cxMemory * ppdev->cyScreen));
// Stereo front buffer
glintInfo->frontRightBufferXY = glintInfo->backRightBufferXY + (ppdev->cyScreen << 16);
glintInfo->bufferRow[3] = glintInfo->bufferOffset[3] =
(glintInfo->bufferOffset[2] + (ppdev->cxMemory * ppdev->cyScreen));
yOrg += (2*ppdev->cyScreen); // Y origin of next buffer
// We successfully allocated stereo buffers so set the flag.
glintInfo->flags |= GLICAP_STEREO_BUFFERS;
}
else
{
// If we aren't in stereo mode then set the right buffers to their
// left equivalents.
glintInfo->frontRightBufferXY = 0;
glintInfo->backRightBufferXY = glintInfo->backBufferXY;
glintInfo->bufferRow[2] = glintInfo->bufferOffset[2] = glintInfo->bufferOffset[1];
glintInfo->bufferRow[3] = glintInfo->bufferOffset[3] = glintInfo->bufferOffset[0];
}
{
// Place the local buffer at end of memory (picks up dedicated page selector).
// Textures are placed between the back buffer and the local buffer memory.
// The width of the local buffer is controlled via a registry variable.
ULONG TopOfLBMemoryDwords ;
// If the screen width is not a multiple of the patch size then
// we allocate a slightly larger Z buffer which is.
if(PatchRemainder = ppdev->cxScreen % PatchWidth)
{
ZScreenWidth = ppdev->cxScreen + (PatchWidth - PatchRemainder);
}
else
{
ZScreenWidth = ppdev->cxScreen;
}
// Store the actual Z buffer width
glintInfo->P3RXLocalBufferWidth = ZScreenWidth;
LOCALBUFFER_PIXEL_COUNT = ppdev->cyScreen * ZScreenWidth ;
// LB offset in units of LB pixels
{
ULONG TotalMemoryInDwords = (ppdev->cyMemory * ppdev->cxMemory) >> (2 - ppdev->cPelSize) ;
// Working in unit of LB pixels, and working backwards from the end of memory
LOCALBUFFER_PIXEL_OFFSET = TotalMemoryInDwords << (2 - LBPelSize) ;
// Ensure the top left of the last patch starts on a patch boundary
LOCALBUFFER_PIXEL_OFFSET -= LOCALBUFFER_PIXEL_OFFSET % (PatchWidth*16);
// Calculate the start of the local buffer memory (used later)
TopOfLBMemoryDwords = (LOCALBUFFER_PIXEL_OFFSET - LOCALBUFFER_PIXEL_COUNT) >> (2 - LBPelSize) ;
// Need to subtract one row of patches because origin is at start of
// last row of patches
LOCALBUFFER_PIXEL_OFFSET -= (ZScreenWidth*16) ;
// Add the offset of the bottom left pixel within the bottom left
// patch.
LOCALBUFFER_PIXEL_OFFSET += PatchWidth*15;
}
DISPDBG((DBGLVL, "bInitializeGlint: P3 cxScreen %i cyScreen %i cPelSize %i", ppdev->cxScreen, ppdev->cyScreen, ppdev->cPelSize));
DISPDBG((DBGLVL, "bInitializeGlint: P3 cxMemory %i cyMemory %i cPelSize %i", ppdev->cxMemory, ppdev->cyMemory, ppdev->cPelSize));
DISPDBG((DBGLVL, "bInitializeGlint: P3 LOCALBUFFER_PIXEL_OFFSET %i LOCALBUFFER_PIXEL_COUNT %i ", LOCALBUFFER_PIXEL_OFFSET, LOCALBUFFER_PIXEL_COUNT));
// Texture memory offset in DWORDS
TEXTURE_MEMORY_OFFSET = (ppdev->cxMemory * yOrg) >> (2 - ppdev->cPelSize);
// Texture size calculation
if (TopOfLBMemoryDwords > TEXTURE_MEMORY_OFFSET)
{
TEXTURE_MEMORY_SIZE = TopOfLBMemoryDwords - TEXTURE_MEMORY_OFFSET ;
}
else
{
TEXTURE_MEMORY_SIZE = 0 ;
}
DISPDBG((DBGLVL, "bInitializeGlint: P3 TEXTURE_MEMORY_OFFSET %i", TEXTURE_MEMORY_OFFSET));
DISPDBG((DBGLVL, "bInitializeGlint: P3 TEXTURE_MEMORY_SIZE in dwords %i", TEXTURE_MEMORY_SIZE));
}
# if DBG
{
ULONG lbS, lbE, tS, tE;
DISPDBG((DBGLVL, "bIGlint: front buffer = 0x%08Xp (%4dL) -> 0x%08Xp (%4dL)", glintInfo->bufferOffset[0], glintInfo->fbWriteOffset[0] >> 16, glintInfo->bufferOffset[0] + (ppdev->cyScreen * ppdev->cxMemory), (glintInfo->fbWriteOffset[0] >> 16) + ppdev->cyScreen));
DISPDBG((DBGLVL, "bIGlint: back buffer = 0x%08Xp (%4dL) -> 0x%08Xp (%4dL)", glintInfo->bufferOffset[1], glintInfo->backBufferXY >> 16, glintInfo->bufferOffset[1] + (ppdev->cyScreen * ppdev->cxMemory), (glintInfo->backBufferXY >> 16) + ppdev->cyScreen));
lbS = LOCALBUFFER_PIXEL_OFFSET - (ZScreenWidth * (ppdev->cyScreen - 1));
lbE = LOCALBUFFER_PIXEL_OFFSET + ZScreenWidth;
if( ppdev->cPelSize >= LBPelSize ) {
lbS = lbS >> (ppdev->cPelSize - LBPelSize);
lbE = lbE >> (ppdev->cPelSize - LBPelSize);
} else {
lbS = lbS << (LBPelSize - ppdev->cPelSize);
lbE = lbE << (LBPelSize - ppdev->cPelSize);
}
lbS /= ppdev->cxMemory; lbE /= ppdev->cxMemory;
DISPDBG((DBGLVL, "bIGlint: local buffer = 0x%08Xp (%4dL) -> 0x%08Xp (%4dL)", LOCALBUFFER_PIXEL_OFFSET - (ZScreenWidth * (ppdev->cyScreen - 1)), lbS, LOCALBUFFER_PIXEL_OFFSET + ZScreenWidth, lbE));
tS = (TEXTURE_MEMORY_OFFSET << (2 - ppdev->cPelSize)) / ppdev->cxMemory;
tE = (TEXTURE_MEMORY_SIZE << (2 - ppdev->cPelSize)) / ppdev->cxMemory;
DISPDBG((DBGLVL, "bIGlint: texture = 0x%08Xx (%4dL) + 0x%08Xx = 0x%08Xx (%4dL)", TEXTURE_MEMORY_OFFSET, tS, TEXTURE_MEMORY_SIZE, TEXTURE_MEMORY_OFFSET + TEXTURE_MEMORY_SIZE, tS + tE));
}
# endif
}
CompletePermediaBuffers:
// work out the fudge factor to add onto VTGVLineNumber to get the current
// video scanline. VTGVLineNumber returns VTGVLimit for the last visible
// line on the screen and 1 for line after that. Use the
// GLINT_GET_VIDEO_SCANLINE macro to retrieve the current scanline.
//
READ_GLINT_CTRL_REG (VTGVLimit, glintInfo->vtgvLimit);
glintInfo->scanFudge = glintInfo->vtgvLimit - ppdev->cyScreen + 1;
// work out partial products for the screen stride. We need to record
// the products for 8, 16 and 32 bit width 'pixels', only one is the
// correct width, but we want to be able to pretend to use 16 and 32
// bit pixels occasionally on an 8 bit pixel framestore for speed.
cPelSize = ppdev->cPelSize;
if(cPelSize == GLINTDEPTH24)
{
// 24bpp: special case (3 bytes per pixel)
width = ppdev->cxMemory * 3;
}
else
{
width = ppdev->cxMemory << cPelSize; // width of framestore in bytes
}
DISPDBG((DBGLVL, "assuming screen stride is %d bytes\n", width));
// Hardware write mask emulation with DRAMS works for byte masks only
// I.e. 0xFF00FF00 will work, 0x0FF00FF0 will not.
READ_GLINT_CTRL_REG( LocalMemCaps, ulValue );
if (ulValue & (1 << 28))
{
glintInfo->flags |= GLICAP_HW_WRITE_MASK_BYTES;
}
else
{
glintInfo->flags |= GLICAP_HW_WRITE_MASK;
}
DISPDBG((DBGLVL, "bInitializeGlint OK"));
#if DBG
// print this stuff out for debugging purposes
if (GLINT_HW_WRITE_MASK)
DISPDBG((DBGLVL, "Hardware Writemasking enabled"));
ASSERTDD(!GLINT_CS_DBL_BUF, "Color Space double buffering enabled");
if (GLINT_FS_DBL_BUF)
{
DISPDBG((DBGLVL, "Full screen double buffering enabled"));
DISPDBG((DBGLVL, "second buffer at pixel offset 0x%x, origin (%d,%d), RowAddr %d",
GLINT_BUFFER_OFFSET(1),
GLINT_BUFFER_OFFSET(1) % ppdev->cxMemory,
GLINT_BUFFER_OFFSET(1) / ppdev->cxMemory,
glintInfo->bufferRow[1]));
}
if (GLINT_BLT_DBL_BUF)
{
DISPDBG((DBGLVL, "BITBLT double buffering enabled"));
DISPDBG((DBGLVL, "second buffer at pixel offset 0x%x, origin (%d,%d)",
GLINT_BUFFER_OFFSET(1),
GLINT_BUFFER_OFFSET(1) % ppdev->cxMemory,
GLINT_BUFFER_OFFSET(1) / ppdev->cxMemory));
}
if (GLINT_FAST_FILL_SIZE > 0)
DISPDBG((DBGLVL, "using fast fill size of %d (%s fast fill bug workarounds)",
GLINT_FAST_FILL_SIZE, GLINT_FIX_FAST_FILL ? "need" : "don't need"));
#endif // DBG
return(TRUE);
} // bInitializeGlint
/******************************Public*Routine******************************\
* VOID vDisableGlint
*
* Do whatever we need to when the surface is disabled.
*
\**************************************************************************/
VOID vDisableGlint(PPDEV ppdev)
{
DSURF* pdsurf;
GLINT_DECL;
if (!glintInfo)
return;
if (glintInfo->PXRXDMABuffer.virtAddr && glintInfo->PXRXDMABuffer.physAddr.LowPart == 0)
{
DISPDBG((DBGLVL, "DrvDisableSurface: "
"freeing PXRX virtual DMA buffer %p, size %xh",
glintInfo->PXRXDMABuffer.virtAddr,
glintInfo->PXRXDMABuffer.size));
ENGFREEMEM(glintInfo->PXRXDMABuffer.virtAddr);
glintInfo->PXRXDMABuffer.virtAddr = NULL;
glintInfo->PXRXDMABuffer.size = 0;
}
// free up any contexts we allocated
//
if (glintInfo->ddCtxtId >= 0)
{
vGlintFreeContext(ppdev, glintInfo->ddCtxtId);
}
//@@BEGIN_DDKSPLIT
#ifdef LATER
pdsurf = ppdev->pdsurfOffScreen;
if (pdsurf != NULL)
vDeleteScreenDIBFromOH(pdsurf->poh);
#endif
//@@END_DDKSPLIT
// Free GlintInfo and zero it.
ENGFREEMEM(glintInfo);
ppdev->glintInfo = NULL;
} // vDisableGlint
/******************************Public*Routine******************************\
* VOID vAssertModeGlint
*
* We're about to switch to/from full screen mode so do whatever we need to
* to save context etc.
*
\**************************************************************************/
VOID vAssertModeGlint(PPDEV ppdev, BOOL bEnable)
{
GLINT_DECL;
if (!glintInfo)
return;
if (!bEnable)
{
// Reset our software copy of the depth configured for this PDEV
// back to the native depth. If we don't do this we may end up
// with the copy and the hardware being out of sync when we
// re-enable. Also, do a context switch to save our core register
// state ready for when we get back in. All this forces a SYNC
// as well which is a good thing.
//
VALIDATE_DD_CONTEXT;
GLINT_DEFAULT_FB_DEPTH;
GLINT_VALIDATE_CONTEXT(-1);
}
else
{
// re-enabling our PDEV so reload our context.
//
VALIDATE_DD_CONTEXT;
//@@BEGIN_DDKSPLIT
#if GAMMA_CORRECTION
//
// Restore the current gamma LUT.
//
bInstallGammaLUT(ppdev, &glintInfo->gammaLUT, FALSE);
#endif // GAMMA_CORRECTION
//@@END_DDKSPLIT
}
} // vAssertModeGlint