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

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: sync.c
  8. *
  9. * Content: DrvSynchronize
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "precomp.h"
  15. #include "pxrx.h"
  16. /******************************Public*Routine******************************\
  17. * VOID DrvSynchronize
  18. *
  19. * Synchronize with the GLINT.
  20. *
  21. * Before letting GDI draw onto our screen DIBs we must synchronize with GLINT.
  22. * We do this by hooking HOOK_SYNCHRONIZE when we create a DIV that points to
  23. * the screen (or off-screen). GDI then calls DrvSynchronize() before trying
  24. * to render to any of these screen DIBs. The advantage is that we can forget
  25. * about doing SYNC_WITH_GLINT in the code and have GDI call DrvSynchronize
  26. * at the appropriate moment.
  27. *
  28. \**************************************************************************/
  29. VOID
  30. DrvSynchronize(
  31. DHPDEV dhpdev,
  32. RECTL *prcl)
  33. {
  34. PDEV* ppdev = (PDEV*) dhpdev;
  35. GLINT_DECL;
  36. DISPDBG((DBGLVL, "DrvSynchronize called"));
  37. // These chips use cached syncs
  38. SYNC_IF_CORE_BUSY;
  39. }
  40. //@@BEGIN_DDKSPLIT
  41. #if 0
  42. #if USE_LD_GLINT_FIFO_FUNCTION
  43. void loadGlintFIFOrelease( GlintDataPtr glintInfo, ULONG tag, ULONG data ) {
  44. /**/
  45. TEMP_MACRO_VARS;
  46. LD_GLINT_FIFO_FREE( tag, data );
  47. /*/
  48. static ULONG fifoSpace = 0;
  49. ULONG *dst;
  50. TEMP_MACRO_VARS;
  51. if( fifoSpace < 2 ) {
  52. GET_INPUT_FIFO_SPACE( fifoSpace );
  53. if ( GLINT_GAMMA_PRESENT ) {
  54. if( space > MAX_GAMMA_FIFO_ENTRIES )
  55. space = MAX_GAMMA_FIFO_ENTRIES;
  56. }
  57. else {
  58. if( space > MAX_P3_FIFO_ENTRIES )
  59. space = MAX_P3_FIFO_ENTRIES;
  60. }
  61. }
  62. dst = (ULONG *) glintInfo->regs.InFIFOInterface;
  63. MEMORY_BARRIER();
  64. WRITE_FAST_ULONG( dst, tag );
  65. dst++;
  66. MEMORY_BARRIER();
  67. WRITE_FAST_ULONG( dst, data );
  68. /**/
  69. }
  70. void loadGlintFIFOdebug( GlintDataPtr glintInfo, ULONG tag, ULONG data ) {
  71. TEMP_MACRO_VARS;
  72. LD_GLINT_FIFO_DBG( tag, data )
  73. }
  74. #if DBG
  75. LoadGlintFIFO loadGlintFIFO = loadGlintFIFOdebug;
  76. #else
  77. LoadGlintFIFO loadGlintFIFO = loadGlintFIFOrelease;
  78. #endif // DBG
  79. #endif // USE_LD_GLINT_FIFO_FUNCTION
  80. #endif // 0
  81. //@@END_DDKSPLIT
  82. #if USE_SYNC_FUNCTION
  83. void syncWithGlint( PPDEV ppdev, GlintDataPtr glintInfo )
  84. {
  85. DWORD gsync;
  86. ULONG bmask;
  87. TEMP_MACRO_VARS;
  88. WAIT_DMA_COMPLETE;
  89. // Setting the pxrxDMA->bFlushRequired flag below to false ensures that
  90. // the interrupt routine will not try to write to the chip. Without
  91. // this check, the Vblank interrupt can attempt to flush outstanding 2D
  92. // rendering by writing ContinueNewSub tag and data to the chip.
  93. // The problem with this is that the interrupt can occur between the
  94. // writes of the tag and data in the code below, and if this happens,
  95. // the tag and data becomes out of step and typically results in a hang.
  96. //
  97. // Note that we have to set a MUTEX otherwise we still get hangs on a
  98. // multi-processor system when an interrupt routine can be running
  99. // simultaneously on another processor. The MUTEX avoids race conditions.
  100. GET_INTR_CMD_BLOCK_MUTEX(&glintInfo->pInterruptCommandBlock->General);
  101. glintInfo->pxrxDMA->bFlushRequired = FALSE ;
  102. WAIT_GLINT_FIFO(4);
  103. LD_GLINT_FIFO(__GlintTagFilterMode, 0x400);
  104. LD_GLINT_FIFO(__GlintTagSync, 0);
  105. LD_GLINT_FIFO(__GlintTagFilterMode, 0x0);
  106. do {
  107. WAIT_OUTPUT_FIFO_READY;
  108. READ_OUTPUT_FIFO(gsync);
  109. DISPDBG((DBGLVL, "SYNC: got 0x%x from output FIFO", gsync));
  110. } while (gsync != __GlintTagSync);
  111. glintInfo->bGlintCoreBusy = FALSE;
  112. RELEASE_INTR_CMD_BLOCK_MUTEX(&glintInfo->pInterruptCommandBlock->General);
  113. }
  114. void waitDMAcomplete( PPDEV ppdev, GlintDataPtr glintInfo )
  115. {
  116. TEMP_MACRO_VARS;
  117. if (ppdev->currentCtxt == glintInfo->ddCtxtId)
  118. {
  119. SEND_PXRX_DMA_FORCE;
  120. }
  121. if (!(ppdev->g_GlintBoardStatus & GLINT_DMA_COMPLETE))
  122. {
  123. if (ppdev->g_GlintBoardStatus & GLINT_INTR_CONTEXT)
  124. {
  125. // do any VBLANK wait, wait Q to empty and last DMA to complete
  126. PINTERRUPT_CONTROL_BLOCK pBlock = glintInfo->pInterruptCommandBlock;
  127. while (pBlock->Control & SUSPEND_DMA_TILL_VBLANK)
  128. {
  129. NULL;
  130. }
  131. while (pBlock->frontIndex != pBlock->backIndex)
  132. {
  133. NULL;
  134. }
  135. }
  136. if ((GET_DMA_COUNT(_temp_volatile_i)) > 0)
  137. {
  138. do
  139. {
  140. while (--_temp_volatile_i > 0)
  141. {
  142. NULL;
  143. }
  144. } while ((GET_DMA_COUNT(_temp_volatile_i)) > 0);
  145. }
  146. ppdev->g_GlintBoardStatus |= GLINT_DMA_COMPLETE;
  147. }
  148. }
  149. #endif // USE_SYNC_FUNCTION