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.
 
 
 
 
 
 

344 lines
11 KiB

/******************************Module*Header**********************************\
*
* *************************
* * GDI/DDRAW SAMPLE CODE *
* *************************
*
* Module Name: ddraw.c
*
* Content: Provides interfaces back from the DDRAW .lib file into the main NT driver
*
* Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
* Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
\*****************************************************************************/
#include "precomp.h"
#include "glint.h"
#if WNT_DDRAW
// The code inside this WNT_DDRAW ifdef is code that interfaces between the DirectDraw
// core (as ported from Win 95) and the Win NT display driver.
/*
* vNTSyncWith2DDriver ()
* --------------------------
*
* Sync DirectDraw with every other subsystem: 2D driver . We
* put it in a function to get at the correct data structures.
*/
VOID vNTSyncWith2DDriver(PPDEV ppdev)
{
GLINT_DECL;
SYNC_WITH_GLINT;
}
// if we're expecting to use the vblank interrupt but the adapter hasn't been allocated an
// interrupt, we'll need to provide temporary storage for values that would otherwise have been
// stored within the interrupt block
ULONG gulOverlayEnabled;
ULONG gulVBLANKUpdateOverlay;
ULONG gulVBLANKUpdateOverlayWidth;
ULONG gulVBLANKUpdateOverlayHeight;
/*
* bSetupOffscreenForDDraw ()
* --------------------------
*
* This function enables and disables the Display Driver's off-screen video memory.
* This allows DirectDraw to take control of the off-screen memory and to
* create it's linear heap in the memory.
*
* Note: only implemented for Permedia.
*/
BOOL bSetupOffscreenForDDraw(
BOOL enableFlag,
PPDEV ppdev,
volatile DWORD **VBlankAddress,
volatile DWORD **bOverlayEnabled,
volatile DWORD **VBLANKUpdateOverlay,
volatile DWORD **VBLANKUpdateOverlayWidth,
volatile DWORD **VBLANKUpdateOverlayHeight)
{
BOOL retVal = TRUE;
PINTERRUPT_CONTROL_BLOCK pBlock;
GLINT_DECL;
DISPDBG((DBGLVL, "bSetupOffscreenForDDraw: in addr 0x%x", VBlankAddress));
if (enableFlag)
{
if((ppdev->flStatus & STAT_LINEAR_HEAP) == 0)
{
// disabling DDraw, reenabling 2D offscreeen
vEnable2DOffscreenMemory(ppdev);
}
// Get pointer to interrupt command block
pBlock = glintInfo->pInterruptCommandBlock;
// Reset the interrupt flags
if (INTERRUPTS_ENABLED && (pBlock->Control & DIRECTDRAW_VBLANK_ENABLED))
{
// Clear the flag to stop the interrupt routine setting the
// flag in the shared structure
pBlock->Control &= ~DIRECTDRAW_VBLANK_ENABLED;
// clear VBLANK flag or we'll get an immediate interrupt
WRITE_GLINT_CTRL_REG(IntFlags, INTR_CLEAR_VBLANK);
// Re-instate the original flags
WRITE_GLINT_CTRL_REG(IntEnable, ppdev->oldIntEnableFlags);
}
}
else
{
// enabling DDraw, disabling 2D offscreen
// We zap off-screen memory chunks on Permedia, only if there
// aren't any OGL apps running.
{
// There aren't any OGL apps running, so grab all the
// memory for DDraw
if(ppdev->flStatus & ENABLE_LINEAR_HEAP)
{
// DX managed linear heap - we don't need to do anything
// NB. check against whether we have the capability to use the linear heap, rather than
// whether it's currently enabled as it's only enabled much later, in DrvNotify
retVal = TRUE;
}
else
retVal = bDisable2DOffscreenMemory(ppdev);
if (retVal == TRUE)
{
// We return a pointer to a 'long' which DirectDraw can
// poll to see if it is zero or not.
if (VBlankAddress != NULL)
{
DWORD enableFlags;
*VBlankAddress = NULL;
if (INTERRUPTS_ENABLED)
{
// Get pointer to interrupt command block
pBlock = glintInfo->pInterruptCommandBlock;
// Indicate that we require the miniport to
// set a flag for us
pBlock->Control |= DIRECTDRAW_VBLANK_ENABLED;
// clear VBLANK flag or we'll get an immediate interrupt
WRITE_GLINT_CTRL_REG(IntFlags, INTR_CLEAR_VBLANK);
// enable the VBLANK interrupt
READ_GLINT_CTRL_REG (IntEnable, enableFlags);
WRITE_GLINT_CTRL_REG(IntEnable, enableFlags | INTR_ENABLE_VBLANK);
// Save the old interrupt flags so that we can restore them
ppdev->oldIntEnableFlags = enableFlags;
// Set up pointers into the shared memory
*VBlankAddress = &pBlock->DDRAW_VBLANK;
*bOverlayEnabled = &pBlock->bOverlayEnabled;
*VBLANKUpdateOverlay = &pBlock->bVBLANKUpdateOverlay;
*VBLANKUpdateOverlayWidth = &pBlock->VBLANKUpdateOverlayWidth;
*VBLANKUpdateOverlayHeight = &pBlock->VBLANKUpdateOverlayHeight;
}
else
{
*bOverlayEnabled = &gulOverlayEnabled;
*VBLANKUpdateOverlay = &gulVBLANKUpdateOverlay;
*VBLANKUpdateOverlayWidth = &gulVBLANKUpdateOverlayWidth;
*VBLANKUpdateOverlayHeight = &gulVBLANKUpdateOverlayHeight;
}
DISPDBG((DBGLVL, "bSetupOffscreenForDDraw: configured ptr 0x%x", *VBlankAddress));
}
}
}
}
DISPDBG((DBGLVL, "bSetupOffscreenForDDraw: exit %d", retVal));
return (retVal);
}
/*
* GetChipInfoForDDraw ()
* ----------------------
*
* A simple helper function to return chip information to DirectDraw
*/
VOID GetChipInfoForDDraw(
PPDEV ppdev,
DWORD* pdwChipID,
DWORD* pdwChipRev,
DWORD* pdwChipFamily,
DWORD* pdwGammaRev)
{
GLINT_DECL;
DISPDBG((DBGLVL,"*** In GetChipInfoForDDraw"));
DISPDBG((DBGLVL," Chip is PXRX Family"));
*pdwChipFamily = PERMEDIA3_ID;
*pdwChipID = glintInfo->deviceInfo.DeviceId;
*pdwChipRev = glintInfo->deviceInfo.RevisionId;
*pdwGammaRev = glintInfo->deviceInfo.GammaRevId;
}
/*
* GetFBLBInfoForDDraw ()
* ----------------------
*
* Return some basic framnebuffer/localbuffer info to DirectDraw.
*/
VOID GetFBLBInfoForDDraw(
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
BOOL *bSDRAM) // TRUE if SDRAM (i.e. no h/w write mask)
{
GLINT_DECL;
*fbPtr = ppdev->pjScreen;
*lbPtr = NULL; // We don't know this one
*fbSizeInBytes = ppdev->FrameBufferLength;
*lbSizeInBytes = TEXTURE_MEMORY_SIZE;
*fbOffsetInBytes = ppdev->heap.DDrawOffscreenStart * ppdev->cjPelSize;
*bSDRAM = (GLINT_HW_WRITE_MASK == FALSE);
DISPDBG((DBGLVL, "GetFBLBInfoForDDraw: offstart 0x%x, buf[1] 0x%lx, pelsz %d",
ppdev->heap.DDrawOffscreenStart,
GLINT_BUFFER_OFFSET(1),
ppdev->cjPelSize));
}
// DDSendDMAData
// Uses DMA to transfer one complete buffer of DDRAW data
// under NT5.
// Before initiating DMA transfer, a check is made to ensure
// that any previous DMA transfer has completed.
// Then the DMA is initiated and the routine returns, so that
// the DMA transfer proceeds in parallel with the processor's
// proceeding execution.
LONG DDSendDMAData(
PDEV* ppdev,
ULONG PhysAddr,
ULONG_PTR VirtAddr,
LONG nDataEntries)
{
ULONG frontIndex, nextIndex;
volatile ULONG ulValue;
GLINT_DECL ;
// PhysAddr += DataOffset;
// VirtAddr += DataOffset;
DISPDBG((DBGLVL, "DMASendData: DMA at 0x%x for %d", PhysAddr, nDataEntries));
ppdev->g_GlintBoardStatus &= ~GLINT_DMA_COMPLETE;
if (ppdev->g_GlintBoardStatus & GLINT_INTR_CONTEXT)
{
PINTERRUPT_CONTROL_BLOCK pBlock = glintInfo->pInterruptCommandBlock;
DISPDBG((DBGLVL, "Processing buffer at 0x%x for %d", PhysAddr, nDataEntries));
DISPDBG((DBGLVL, "Adding buffer to Q"));
frontIndex = pBlock->frontIndex;
if ((nextIndex = frontIndex+1) == pBlock->endIndex)
nextIndex = 0;
// wait for a free queue entry. We should really do a backoff here.
while (nextIndex == pBlock->backIndex);
DISPDBG((DBGLVL, "Add to DMA Q backindex %d frontindex %d",frontIndex, pBlock->backIndex));
// add the DMA address and count to the new entry.
pBlock->dmaQueue[frontIndex].address = PhysAddr;
pBlock->dmaQueue[frontIndex].count = nDataEntries;
pBlock->frontIndex = nextIndex;
// wakeup the interrupt handler using an error interrupt. To save on
// interrupt processing, only do this if a DMA interrupt is not
// pending.
//
//if (!pBlock->InterruptPending)
{
DISPDBG((DBGLVL, "Generating error interrupt"));
WRITE_GLINT_CTRL_REG(ErrorFlags, 0x7); // clear error flags
READ_OUTPUT_FIFO(ulValue); // generate interrupt
}
}
else
{
WAIT_IMMEDIATE_DMA_COMPLETE;
SET_DMA_ADDRESS(PhysAddr, VirtAddr) ;
SET_DMA_COUNT(nDataEntries);
}
DISPDBG((DBGLVL,"DMA count=%d\n", nDataEntries )) ;
return 1 ;
}
// Wrapper function used for requesting a DMA memory buffer
// from NT for use by D3D. NT 5 only.
LONG DDGetFreeDMABuffer(
DWORD *physAddr,
ULONG_PTR *virtAddr,
DWORD *bufferSize)
{
LONG BuffNum;
QUERY_DMA_BUFFERS dmaBuffer;
BuffNum = GetFreeDMABuffer(&dmaBuffer);
if (BuffNum >= 0)
{
*physAddr = (DWORD)dmaBuffer.physAddr.LowPart;
*virtAddr = (ULONG_PTR)dmaBuffer.virtAddr;
*bufferSize = (DWORD)dmaBuffer.size;
}
else
{
// Failed to get a free DMA buffer
*physAddr = 0;
*virtAddr = 0;
*bufferSize = 0;
}
return BuffNum;
}
// Frees the given DMA buffer.
VOID DDFreeDMABuffer(void* pPhysAddress)
{
FreeDMABuffer(pPhysAddress);
return;
}
LONG DDWaitDMAComplete(PDEV *ppdev)
{
GLINT_DECL ;
WAIT_DMA_COMPLETE;
return 0;
}
#endif WNT_DDRAW