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.
 
 
 
 
 
 

187 lines
5.2 KiB

/******************************Module*Header**********************************\
*
* *******************
* * GDI SAMPLE CODE *
* *******************
*
* Module Name: sync.c
*
* Content: DrvSynchronize
*
* 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"
/******************************Public*Routine******************************\
* VOID DrvSynchronize
*
* Synchronize with the GLINT.
*
* Before letting GDI draw onto our screen DIBs we must synchronize with GLINT.
* We do this by hooking HOOK_SYNCHRONIZE when we create a DIV that points to
* the screen (or off-screen). GDI then calls DrvSynchronize() before trying
* to render to any of these screen DIBs. The advantage is that we can forget
* about doing SYNC_WITH_GLINT in the code and have GDI call DrvSynchronize
* at the appropriate moment.
*
\**************************************************************************/
VOID
DrvSynchronize(
DHPDEV dhpdev,
RECTL *prcl)
{
PDEV* ppdev = (PDEV*) dhpdev;
GLINT_DECL;
DISPDBG((DBGLVL, "DrvSynchronize called"));
// These chips use cached syncs
SYNC_IF_CORE_BUSY;
}
//@@BEGIN_DDKSPLIT
#if 0
#if USE_LD_GLINT_FIFO_FUNCTION
void loadGlintFIFOrelease( GlintDataPtr glintInfo, ULONG tag, ULONG data ) {
/**/
TEMP_MACRO_VARS;
LD_GLINT_FIFO_FREE( tag, data );
/*/
static ULONG fifoSpace = 0;
ULONG *dst;
TEMP_MACRO_VARS;
if( fifoSpace < 2 ) {
GET_INPUT_FIFO_SPACE( fifoSpace );
if ( GLINT_GAMMA_PRESENT ) {
if( space > MAX_GAMMA_FIFO_ENTRIES )
space = MAX_GAMMA_FIFO_ENTRIES;
}
else {
if( space > MAX_P3_FIFO_ENTRIES )
space = MAX_P3_FIFO_ENTRIES;
}
}
dst = (ULONG *) glintInfo->regs.InFIFOInterface;
MEMORY_BARRIER();
WRITE_FAST_ULONG( dst, tag );
dst++;
MEMORY_BARRIER();
WRITE_FAST_ULONG( dst, data );
/**/
}
void loadGlintFIFOdebug( GlintDataPtr glintInfo, ULONG tag, ULONG data ) {
TEMP_MACRO_VARS;
LD_GLINT_FIFO_DBG( tag, data )
}
#if DBG
LoadGlintFIFO loadGlintFIFO = loadGlintFIFOdebug;
#else
LoadGlintFIFO loadGlintFIFO = loadGlintFIFOrelease;
#endif // DBG
#endif // USE_LD_GLINT_FIFO_FUNCTION
#endif // 0
//@@END_DDKSPLIT
#if USE_SYNC_FUNCTION
void syncWithGlint( PPDEV ppdev, GlintDataPtr glintInfo )
{
DWORD gsync;
ULONG bmask;
TEMP_MACRO_VARS;
WAIT_DMA_COMPLETE;
// Setting the pxrxDMA->bFlushRequired flag below to false ensures that
// the interrupt routine will not try to write to the chip. Without
// this check, the Vblank interrupt can attempt to flush outstanding 2D
// rendering by writing ContinueNewSub tag and data to the chip.
// The problem with this is that the interrupt can occur between the
// writes of the tag and data in the code below, and if this happens,
// the tag and data becomes out of step and typically results in a hang.
//
// Note that we have to set a MUTEX otherwise we still get hangs on a
// multi-processor system when an interrupt routine can be running
// simultaneously on another processor. The MUTEX avoids race conditions.
GET_INTR_CMD_BLOCK_MUTEX(&glintInfo->pInterruptCommandBlock->General);
glintInfo->pxrxDMA->bFlushRequired = FALSE ;
WAIT_GLINT_FIFO(4);
LD_GLINT_FIFO(__GlintTagFilterMode, 0x400);
LD_GLINT_FIFO(__GlintTagSync, 0);
LD_GLINT_FIFO(__GlintTagFilterMode, 0x0);
do {
WAIT_OUTPUT_FIFO_READY;
READ_OUTPUT_FIFO(gsync);
DISPDBG((DBGLVL, "SYNC: got 0x%x from output FIFO", gsync));
} while (gsync != __GlintTagSync);
glintInfo->bGlintCoreBusy = FALSE;
RELEASE_INTR_CMD_BLOCK_MUTEX(&glintInfo->pInterruptCommandBlock->General);
}
void waitDMAcomplete( PPDEV ppdev, GlintDataPtr glintInfo )
{
TEMP_MACRO_VARS;
if (ppdev->currentCtxt == glintInfo->ddCtxtId)
{
SEND_PXRX_DMA_FORCE;
}
if (!(ppdev->g_GlintBoardStatus & GLINT_DMA_COMPLETE))
{
if (ppdev->g_GlintBoardStatus & GLINT_INTR_CONTEXT)
{
// do any VBLANK wait, wait Q to empty and last DMA to complete
PINTERRUPT_CONTROL_BLOCK pBlock = glintInfo->pInterruptCommandBlock;
while (pBlock->Control & SUSPEND_DMA_TILL_VBLANK)
{
NULL;
}
while (pBlock->frontIndex != pBlock->backIndex)
{
NULL;
}
}
if ((GET_DMA_COUNT(_temp_volatile_i)) > 0)
{
do
{
while (--_temp_volatile_i > 0)
{
NULL;
}
} while ((GET_DMA_COUNT(_temp_volatile_i)) > 0);
}
ppdev->g_GlintBoardStatus |= GLINT_DMA_COMPLETE;
}
}
#endif // USE_SYNC_FUNCTION