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

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: glntinit.c
  8. *
  9. * Content: Initialisation for the GLINT chip.
  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. #define FOUR_MB (4*1024*1024)
  17. #define AGP_LONG_READ_DISABLE (1<<3)
  18. /******************************Public*Routine******************************\
  19. * VOID vInitCoreRegisters
  20. *
  21. \**************************************************************************/
  22. VOID vInitCoreRegisters(PPDEV ppdev)
  23. {
  24. ULONG f, b;
  25. GLINT_DECL;
  26. if (glintInfo->pxrxFlags & PXRX_FLAGS_DUAL_WRITE)
  27. {
  28. f = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT) ? 1 : 0;
  29. b = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK ) ? 1 : 0;
  30. }
  31. else
  32. {
  33. f = b = (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_FRONT) ? 1 : 0;
  34. }
  35. glintInfo->foregroundColour = 0x33BADBAD;
  36. glintInfo->backgroundColour = 0x33BAAAAD;
  37. glintInfo->config2D = 0;
  38. glintInfo->backBufferXY = MAKEDWORD_XY(0, ppdev->cyScreen); // This is set properly in bInitializeGlint
  39. glintInfo->frontRightBufferXY = MAKEDWORD_XY(0, ppdev->cyScreen);
  40. glintInfo->backRightBufferXY = MAKEDWORD_XY(0, ppdev->cyScreen);
  41. glintInfo->fbDestMode = (1 << 8) | (1 << 1) | (f << 12) | (b << 14);
  42. if (glintInfo->pxrxFlags & PXRX_FLAGS_STEREO_WRITE)
  43. {
  44. glintInfo->fbDestMode |= (b << 16) | (f << 18);
  45. }
  46. glintInfo->fbDestAddr[0] = 0x00000000;
  47. glintInfo->fbDestAddr[1] = 0x00000000;
  48. glintInfo->fbDestAddr[2] = 0x00000000;
  49. glintInfo->fbDestAddr[3] = 0x00000000;
  50. glintInfo->fbDestWidth[0] = ppdev->cxMemory;
  51. glintInfo->fbDestWidth[1] = ppdev->cxMemory;
  52. glintInfo->fbDestWidth[2] = ppdev->cxMemory;
  53. glintInfo->fbDestWidth[3] = ppdev->cxMemory;
  54. glintInfo->fbDestOffset[0] = 0;
  55. glintInfo->fbDestOffset[1] = 0;
  56. glintInfo->fbDestOffset[2] = 0;
  57. glintInfo->fbDestOffset[3] = 0;
  58. glintInfo->fbWriteAddr[0] = 0x00000000;
  59. glintInfo->fbWriteAddr[1] = 0x00000000;
  60. glintInfo->fbWriteAddr[2] = 0x00000000;
  61. glintInfo->fbWriteAddr[3] = 0x00000000;
  62. glintInfo->fbWriteWidth[0] = ppdev->cxMemory;
  63. glintInfo->fbWriteWidth[1] = ppdev->cxMemory;
  64. glintInfo->fbWriteWidth[2] = ppdev->cxMemory;
  65. glintInfo->fbWriteWidth[3] = ppdev->cxMemory;
  66. glintInfo->fbWriteOffset[0] = 0;
  67. glintInfo->fbWriteOffset[1] = 0;
  68. glintInfo->fbWriteOffset[2] = 0;
  69. glintInfo->fbWriteOffset[3] = 0;
  70. glintInfo->fbSourceAddr = 0x00000000;
  71. glintInfo->fbSourceWidth = ppdev->cxMemory;
  72. glintInfo->fbSourceOffset = 0;
  73. glintInfo->lutMode = 0;
  74. glintInfo->lastLine = 0;
  75. glintInfo->render2Dpatching = 0;
  76. pxrxSetupDualWrites_Patching(ppdev);
  77. pxrxRestore2DContext(ppdev, TRUE);
  78. // Set the cache flag to say that there is no cache info
  79. ppdev->cFlags = 0;
  80. } // vInitCoreRegisters
  81. /******************************Public*Routine******************************\
  82. * BOOL bAllocateGlintInfo
  83. *
  84. * Allocate ppdev->glintInfo and initialise the board info. We need to do
  85. * this as early as possible because we're getting to the point where we
  86. * need to know the board type very early.
  87. \**************************************************************************/
  88. BOOL bAllocateGlintInfo(PPDEV ppdev)
  89. {
  90. GlintDataPtr glintInfo;
  91. ULONG Length;
  92. // Allocate and initialize ppdev->glintInfo.
  93. // We store GLINT specific stuff in this structure.
  94. glintInfo = (PVOID)ENGALLOCMEM(FL_ZERO_MEMORY,
  95. sizeof(GlintDataRec),
  96. ALLOC_TAG_GDI(A));
  97. if (glintInfo == NULL)
  98. {
  99. DISPDBG((ERRLVL, "cannot allocate memory for glintInfo struct"));
  100. return(FALSE);
  101. }
  102. glintInfo->bGlintCoreBusy = TRUE;
  103. ppdev->glintInfo = (PVOID)glintInfo;
  104. // retrieve the PCI configuration information and local buffer size
  105. Length = sizeof(Glint_Device_Info);
  106. if (EngDeviceIoControl(ppdev->hDriver,
  107. IOCTL_VIDEO_QUERY_DEVICE_INFO,
  108. NULL,
  109. 0,
  110. (PVOID)&(glintInfo->deviceInfo),
  111. Length,
  112. &Length))
  113. {
  114. DISPDBG((ERRLVL, "QUERY_DEVICE_INFO failed."));
  115. return(FALSE);
  116. }
  117. return(TRUE);
  118. } // bAllocateGlintInfo
  119. /******************************Public*Routine******************************\
  120. * BOOL bInitializeGlint
  121. *
  122. * Called to load the initial values into the chip. We assume the hardware
  123. * has been mapped. All the relevant stuff should be hanging off ppdev. We
  124. * also sort out all the GLINT capabilities etc.
  125. \**************************************************************************/
  126. BOOL bInitializeGlint(PPDEV ppdev)
  127. {
  128. pGlintControlRegMap pCtrlRegs;
  129. pGlintControlRegMap pCtrlRegsVTG;
  130. pGlintControlRegMap pCtrlRegsOdd;
  131. pGlintCoreRegMap pCoreRegs;
  132. pGlintCoreRegMap pCoreRegsRd;
  133. pGlintCoreRegMap pCoreRegsOdd;
  134. DSURF* pdsurf;
  135. OH *poh = NULL;
  136. LONG cPelSize;
  137. LONG cx, cy;
  138. LONG i, j;
  139. ULONG width;
  140. ULONG ulValue;
  141. BOOL bExists;
  142. BOOL bCreateBackBuffer;
  143. BOOL bCreateStereoBuffers;
  144. ULONG Length;
  145. LONG FinalTag;
  146. GLINT_DECL;
  147. DISPDBG((DBGLVL, "bInitializeGlint: fbsize: 0x%x", ppdev->FrameBufferLength));
  148. glintInfo->ddCtxtId = -1; // initialize to no context
  149. glintInfo->LineDMABuffer.virtAddr = 0; // Initialise these values
  150. glintInfo->LineDMABuffer.size = 0;
  151. glintInfo->PXRXDMABuffer.virtAddr = 0;
  152. glintInfo->PXRXDMABuffer.size = 0;
  153. ppdev->DMABuffer.pphysStart.HighPart = 0;
  154. ppdev->DMABuffer.pphysStart.LowPart = 0;
  155. ppdev->DMABuffer.cb = 0;
  156. ppdev->DMABuffer.pulStart = NULL;
  157. ppdev->DMABuffer.pulCurrent = NULL;
  158. ppdev->DMABuffer.pulEnd = NULL;
  159. Length = sizeof(GENERAL_DMA_BUFFER);
  160. ulValue = 1;
  161. if (EngDeviceIoControl(ppdev->hDriver,
  162. IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER,
  163. &ulValue,
  164. sizeof(ulValue),
  165. (PVOID)&(glintInfo->LineDMABuffer),
  166. Length,
  167. &Length))
  168. {
  169. DISPDBG((ERRLVL, "QUERY_LINE_DMA_BUFFER failed."));
  170. DISPDBG((ERRLVL, "FATAL ERROR: DRIVER REQUIRES DMA BUFFER FOR 2D"
  171. " - UNLOADING DRIVER"));
  172. return(FALSE);
  173. }
  174. bExists = bGlintQueryRegistryValueUlong( ppdev, L"PXRX.DisableDMA", &i );
  175. if ((bExists && !i) || !bExists)
  176. {
  177. Length = sizeof(GENERAL_DMA_BUFFER);
  178. ulValue = 2;
  179. if (EngDeviceIoControl(ppdev->hDriver,
  180. IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER,
  181. &ulValue,
  182. sizeof(ulValue),
  183. (PVOID) &glintInfo->PXRXDMABuffer,
  184. Length,
  185. &Length))
  186. {
  187. DISPDBG((DBGLVL, "QUERY_DMA_BUFFER failed for the PXRX buffer."));
  188. return FALSE;
  189. }
  190. DISPDBG((DBGLVL, "QUERY_DMA_BUFFER(PxRx): P:0x%X:%08X, V:0x%08X, S:%dKb, %s",
  191. glintInfo->PXRXDMABuffer.physAddr.HighPart, glintInfo->PXRXDMABuffer.physAddr.LowPart,
  192. glintInfo->PXRXDMABuffer.virtAddr, glintInfo->PXRXDMABuffer.size / 1024,
  193. glintInfo->PXRXDMABuffer.cacheEnabled ? "Cached" : "Uncached"));
  194. }
  195. #if DBG
  196. else
  197. {
  198. GENERAL_DMA_BUFFER dmaBuff;
  199. Length = sizeof(GENERAL_DMA_BUFFER);
  200. ulValue = 2;
  201. if( EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_QUERY_GENERAL_DMA_BUFFER,
  202. &ulValue, sizeof(ulValue), (PVOID) &dmaBuff,
  203. Length, &Length) ) {
  204. DISPDBG((ERRLVL, "QUERY_DMA_BUFFER failed for the PXRX buffer."));
  205. return FALSE;
  206. }
  207. DISPDBG((DBGLVL, "QUERY_DMA_BUFFER(???): P:0x%X:%08X, V:0x%08X, S:%dKb, %s",
  208. dmaBuff.physAddr.HighPart, dmaBuff.physAddr.LowPart, dmaBuff.virtAddr, dmaBuff.size / 1024,
  209. dmaBuff.cacheEnabled ? "Cached" : "Uncached"));
  210. }
  211. #endif
  212. //@@BEGIN_DDKSPLIT
  213. // TMM: Temporary until we fix s/w cursors. Disable s/w cursor.
  214. ppdev->flStatus &= ~ENABLE_POINTER_CACHE;
  215. //@@END_DDKSPLIT
  216. // Clear the patching flags to begin with
  217. glintInfo->pxrxFlags &= ~(PXRX_FLAGS_PATCHING_FRONT | PXRX_FLAGS_PATCHING_BACK);
  218. // the 2D driver can use the line buffer for other things as well, such as for text rendering
  219. ppdev->DMABuffer.pphysStart = glintInfo->LineDMABuffer.physAddr;
  220. ppdev->DMABuffer.cb = glintInfo->LineDMABuffer.size;
  221. ppdev->DMABuffer.pulStart = glintInfo->LineDMABuffer.virtAddr;
  222. ppdev->DMABuffer.pulCurrent = glintInfo->LineDMABuffer.virtAddr;
  223. ppdev->DMABuffer.pulEnd = ppdev->DMABuffer.pulStart + glintInfo->LineDMABuffer.size - 1;
  224. // set-up the DMA board status - we'll program the registers later
  225. ppdev->g_GlintBoardStatus = GLINT_DMA_COMPLETE;
  226. // Init whether or not GDI is allowed to access framebuffer.
  227. // This must be a variable as it is affected by overlays.
  228. glintInfo->GdiCantAccessFramebuffer = ((ppdev->flCaps & CAPS_SPARSE_SPACE) == CAPS_SPARSE_SPACE);
  229. DISPDBG((WRNLVL, "deviceInfo: GdiCantAccessFramebuffer %d", glintInfo->GdiCantAccessFramebuffer));
  230. 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",
  231. glintInfo->deviceInfo.VendorId,
  232. glintInfo->deviceInfo.DeviceId,
  233. glintInfo->deviceInfo.GammaRevId,
  234. glintInfo->deviceInfo.RevisionId,
  235. glintInfo->deviceInfo.SubsystemId,
  236. glintInfo->deviceInfo.SubsystemVendorId,
  237. glintInfo->deviceInfo.LocalbufferLength,
  238. glintInfo->deviceInfo.LocalbufferWidth));
  239. // collect flags as we initialize so zero it here
  240. glintInfo->flags = 0;
  241. //@@BEGIN_DDKSPLIT
  242. #if 0
  243. // Try to establish color space double buffering. The actual method
  244. // depends on the RAMDAC so call the appropriate routine depending on
  245. // the one we support.
  246. //
  247. bExists = ppdev->pgfnPointerCheckCSBuffering(ppdev);
  248. if (bExists)
  249. {
  250. glintInfo->flags |= GLICAP_COLOR_SPACE_DBL_BUF;
  251. }
  252. #endif
  253. //@@END_DDKSPLIT
  254. // optional DrvCopyBits acceleration for downloads
  255. ppdev->pgfnCopyXferImage = NULL;
  256. ppdev->pgfnCopyXfer24bpp = NULL;
  257. ppdev->pgfnCopyXfer16bpp = NULL;
  258. ppdev->pgfnCopyXfer8bppLge = NULL;
  259. ppdev->pgfnCopyXfer8bpp = NULL;
  260. ppdev->pgfnCopyXfer4bpp = NULL;
  261. // optional NT5 acceleration functions
  262. #if(_WIN32_WINNT >= 0x500)
  263. ppdev->pgfnGradientFillRect = NULL;
  264. ppdev->pgfnTransparentBlt = NULL;
  265. ppdev->pgfnAlphaBlend = NULL;
  266. #endif
  267. //@@BEGIN_DDKSPLIT
  268. // if we're simulating from boot-up then it's OK to use our preferred text method
  269. // HIDEYUKN, temporary disable host memory cache, until figure out more detail.
  270. // ppdev->PreferredGlyphRenderingMethod = GLYPH_HOSTMEM_CACHE;
  271. //@@END_DDKSPLIT
  272. glintInfo->usePXRXdma = USE_PXRX_DMA_FIFO;
  273. pxrxSetupFunctionPointers( ppdev );
  274. // Do the translates for all the GLINT registers we use. For dual-TX
  275. // pCoreRegs points at core registers through Delta
  276. // pCtrlRegs points at Delta
  277. // pCtrlRegsVTG points at the TX with the RAMDAC
  278. // pCtrlRegsOdd points at the non-VTG TX (odd owned scanlines for 3D)
  279. //
  280. pCtrlRegs =
  281. pCtrlRegsVTG = (pGlintControlRegMap)ppdev->pulCtrlBase[0];
  282. pCtrlRegsOdd = (pGlintControlRegMap)ppdev->pulCtrlBase[1];
  283. pCoreRegs = &(pCtrlRegs->coreRegs);
  284. pCoreRegsOdd = &(pCtrlRegsOdd->coreRegs);
  285. pCoreRegsRd = &(pCtrlRegsVTG->coreRegs);
  286. glintInfo->BroadcastMask2D = DELTA_BROADCAST_TO_CHIP(0);
  287. glintInfo->BroadcastMask3D = DELTA_BROADCAST_TO_BOTH_CHIPS;
  288. if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
  289. {
  290. glintInfo->BroadcastMask2D = DELTA_BROADCAST_TO_BOTH_CHIPS;
  291. pCtrlRegsVTG = (pGlintControlRegMap)ppdev->pulCtrlBase[1];
  292. }
  293. ppdev->pulRamdacBase = (PVOID)&(pCtrlRegsVTG->ExternalVideo);
  294. // FIFO registers. Translate all possible tags
  295. FinalTag = __MaximumGlintTagValue;
  296. // record the maximum number if free FIFO entries
  297. if( GLINT_GAMMA_PRESENT ) {
  298. glintInfo->MaxInFifoEntries = MAX_GAMMA_FIFO_ENTRIES;
  299. } else {
  300. glintInfo->MaxInFifoEntries = MAX_P3_FIFO_ENTRIES;
  301. }
  302. // Chip tags may be read/written from different address spaces
  303. for (i = 0; i < __DeltaTagV0Fixed0; ++i)
  304. {
  305. glintInfo->regs.tagwr[i] =
  306. TRANSLATE_ADDR(&(pCoreRegs->tag[i]));
  307. glintInfo->regs.tagrd[i] =
  308. TRANSLATE_ADDR(&(pCoreRegsRd->tag[i]));
  309. }
  310. // Delta tags are read/written from the same address space
  311. for (i = __DeltaTagV0Fixed0; i <= FinalTag; ++i)
  312. {
  313. glintInfo->regs.tagwr[i] =
  314. TRANSLATE_ADDR(&(pCoreRegs->tag[i]));
  315. glintInfo->regs.tagrd[i] =
  316. TRANSLATE_ADDR(&(pCoreRegs->tag[i]));
  317. }
  318. // non-FIFO control registers
  319. glintInfo->regs.LBMemoryCtl =
  320. TRANSLATE_ADDR(&(pCtrlRegsVTG->LBMemoryCtl));
  321. glintInfo->regs.LBMemoryEDO =
  322. TRANSLATE_ADDR(&(pCtrlRegsVTG->LBMemoryEDO));
  323. glintInfo->regs.FBMemoryCtl =
  324. TRANSLATE_ADDR(&(pCtrlRegsVTG->FBMemoryCtl));
  325. glintInfo->regs.FBModeSel =
  326. TRANSLATE_ADDR(&(pCtrlRegs->FBModeSel));
  327. glintInfo->regs.FBModeSelOdd =
  328. TRANSLATE_ADDR(&(pCtrlRegsOdd->FBModeSel));
  329. glintInfo->regs.VTGHLimit =
  330. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHLimit));
  331. glintInfo->regs.VTGHSyncStart =
  332. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHSyncStart));
  333. glintInfo->regs.VTGHSyncEnd =
  334. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHSyncEnd));
  335. glintInfo->regs.VTGHBlankEnd =
  336. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHBlankEnd));
  337. glintInfo->regs.VTGHGateStart =
  338. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHGateStart));
  339. glintInfo->regs.VTGHGateEnd =
  340. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGHGateEnd));
  341. glintInfo->regs.VTGVLimit =
  342. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVLimit));
  343. glintInfo->regs.VTGVSyncStart =
  344. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVSyncStart));
  345. glintInfo->regs.VTGVSyncEnd =
  346. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVSyncEnd));
  347. glintInfo->regs.VTGVBlankEnd =
  348. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVBlankEnd));
  349. glintInfo->regs.VTGVGateStart =
  350. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVGateStart));
  351. glintInfo->regs.VTGVGateEnd =
  352. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVGateEnd));
  353. glintInfo->regs.VTGPolarity =
  354. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGPolarity));
  355. glintInfo->regs.VTGVLineNumber =
  356. TRANSLATE_ADDR(&(pCtrlRegsVTG->VTGVLineNumber));
  357. glintInfo->regs.VTGFrameRowAddr =
  358. TRANSLATE_ADDR(&(pCtrlRegs->VTGFrameRowAddr));
  359. glintInfo->regs.VTGFrameRowAddrOdd =
  360. TRANSLATE_ADDR(&(pCtrlRegsOdd->VTGFrameRowAddr));
  361. glintInfo->regs.InFIFOSpace =
  362. TRANSLATE_ADDR(&(pCtrlRegs->InFIFOSpace));
  363. glintInfo->regs.OutFIFOWords =
  364. TRANSLATE_ADDR(&(pCtrlRegs->OutFIFOWords));
  365. glintInfo->regs.OutFIFOWordsOdd =
  366. TRANSLATE_ADDR(&(pCtrlRegsOdd->OutFIFOWords));
  367. glintInfo->regs.DMAAddress =
  368. TRANSLATE_ADDR(&(pCtrlRegs->DMAAddress));
  369. glintInfo->regs.DMACount =
  370. TRANSLATE_ADDR(&(pCtrlRegs->DMACount));
  371. glintInfo->regs.InFIFOInterface =
  372. TRANSLATE_ADDR(&(pCtrlRegs->FIFOInterface));
  373. glintInfo->regs.OutFIFOInterface =
  374. TRANSLATE_ADDR(&(pCtrlRegs->FIFOInterface));
  375. glintInfo->regs.OutFIFOInterfaceOdd =
  376. TRANSLATE_ADDR(&(pCtrlRegsOdd->FIFOInterface));
  377. glintInfo->regs.IntFlags =
  378. TRANSLATE_ADDR(&(pCtrlRegs->IntFlags));
  379. glintInfo->regs.IntEnable =
  380. TRANSLATE_ADDR(&(pCtrlRegs->IntEnable));
  381. glintInfo->regs.ResetStatus =
  382. TRANSLATE_ADDR(&(pCtrlRegs->ResetStatus));
  383. glintInfo->regs.ErrorFlags =
  384. TRANSLATE_ADDR(&(pCtrlRegs->ErrorFlags));
  385. glintInfo->regs.DeltaIntFlags =
  386. TRANSLATE_ADDR(&(pCtrlRegs->DeltaIntFlags));
  387. glintInfo->regs.DeltaIntEnable =
  388. TRANSLATE_ADDR(&(pCtrlRegs->DeltaIntEnable));
  389. glintInfo->regs.DeltaErrorFlags =
  390. TRANSLATE_ADDR(&(pCtrlRegs->DeltaErrorFlags));
  391. glintInfo->regs.ScreenBase =
  392. TRANSLATE_ADDR(&(pCtrlRegsVTG->ScreenBase));
  393. glintInfo->regs.ScreenBaseRight =
  394. TRANSLATE_ADDR(&(pCtrlRegsVTG->ScreenBaseRight));
  395. glintInfo->regs.LineCount =
  396. TRANSLATE_ADDR(&(pCtrlRegsVTG->LineCount));
  397. glintInfo->regs.VbEnd =
  398. TRANSLATE_ADDR(&(pCtrlRegsVTG->VbEnd));
  399. glintInfo->regs.VideoControl =
  400. TRANSLATE_ADDR(&(pCtrlRegsVTG->VideoControl));
  401. glintInfo->regs.MemControl =
  402. TRANSLATE_ADDR(&(pCtrlRegsVTG->MemControl));
  403. glintInfo->regs.VTGSerialClk =
  404. TRANSLATE_ADDR(&(pCtrlRegs->VTGSerialClk));
  405. glintInfo->regs.VTGSerialClkOdd =
  406. TRANSLATE_ADDR(&(pCtrlRegsOdd->VTGSerialClk));
  407. glintInfo->regs.VClkCtl =
  408. TRANSLATE_ADDR(&(pCtrlRegsVTG->VClkCtl));
  409. glintInfo->regs.RacerDoubleWrite =
  410. TRANSLATE_ADDR(&(pCtrlRegsVTG->RacerDoubleWrite));
  411. glintInfo->regs.RacerBankSelect =
  412. TRANSLATE_ADDR(&(pCtrlRegsVTG->RacerBankSelect));
  413. //@@BEGIN_DDKSPLIT
  414. // TMM: Add support for Omnicomp 3Demon Pro16
  415. //@@END_DDKSPLIT
  416. glintInfo->regs.DemonProDWAndStatus =
  417. TRANSLATE_ADDR(&(pCtrlRegsVTG->DemonProDWAndStatus));
  418. glintInfo->regs.DemonProUBufB =
  419. TRANSLATE_ADDR(&(pCtrlRegsVTG->DemonProUBufB));
  420. glintInfo->regs.DisconnectControl =
  421. TRANSLATE_ADDR(&(pCtrlRegs->DisconnectControl));
  422. // The following regs are P2 only - but it should be safe to calculate them for
  423. // any chipset
  424. glintInfo->regs.OutDMAAddress =
  425. TRANSLATE_ADDR(&(pCtrlRegs->OutDMAAddress));
  426. glintInfo->regs.OutDMACount =
  427. TRANSLATE_ADDR(&(pCtrlRegs->OutDMACount));
  428. glintInfo->regs.DMAControl =
  429. TRANSLATE_ADDR(&(pCtrlRegs->DMAControl));
  430. glintInfo->regs.AGPControl =
  431. TRANSLATE_ADDR(&(pCtrlRegs->AGPControl));
  432. glintInfo->regs.ByDMAAddress =
  433. TRANSLATE_ADDR(&(pCtrlRegs->ByDMAAddress));
  434. glintInfo->regs.ByDMAStride =
  435. TRANSLATE_ADDR(&(pCtrlRegs->ByDMAStride));
  436. glintInfo->regs.ByDMAMemAddr =
  437. TRANSLATE_ADDR(&(pCtrlRegs->ByDMAMemAddr));
  438. glintInfo->regs.ByDMASize =
  439. TRANSLATE_ADDR(&(pCtrlRegs->ByDMASize));
  440. glintInfo->regs.ByDMAByteMask =
  441. TRANSLATE_ADDR(&(pCtrlRegs->ByDMAByteMask));
  442. glintInfo->regs.ByDMAControl =
  443. TRANSLATE_ADDR(&(pCtrlRegs->ByDMAControl));
  444. glintInfo->regs.ByDMAComplete =
  445. TRANSLATE_ADDR(&(pCtrlRegs->ByDMAComplete));
  446. glintInfo->regs.VSConfiguration =
  447. TRANSLATE_ADDR(&(pCtrlRegs->VSConfiguration));
  448. glintInfo->regs.TextureDownloadControl =
  449. TRANSLATE_ADDR(&(pCtrlRegs->TextureDownloadControl));
  450. glintInfo->regs.LocalMemCaps =
  451. TRANSLATE_ADDR(&(pCtrlRegs->LocalMemCaps));
  452. glintInfo->regs.MemScratch =
  453. TRANSLATE_ADDR(&(pCtrlRegs->MemScratch));
  454. // The following regs are Gamma only - but it should be safe to calculate them for
  455. // any chipset
  456. glintInfo->regs.GammaCommandMode =
  457. TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandMode));
  458. glintInfo->regs.GammaCommandIntEnable =
  459. TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandIntEnable));
  460. glintInfo->regs.GammaCommandIntFlags =
  461. TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandIntFlags));
  462. glintInfo->regs.GammaCommandErrorFlags =
  463. TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandErrorFlags));
  464. glintInfo->regs.GammaCommandStatus =
  465. TRANSLATE_ADDR(&(pCtrlRegs->GammaCommandStatus));
  466. glintInfo->regs.GammaFeedbackSelectCount =
  467. TRANSLATE_ADDR(&(pCtrlRegs->GammaFeedbackSelectCount));
  468. glintInfo->regs.GammaProcessorMode =
  469. TRANSLATE_ADDR(&(pCtrlRegs->GammaProcessorMode));
  470. glintInfo->regs.GammaChipConfig =
  471. TRANSLATE_ADDR(&(pCtrlRegs->GammaChipConfig));
  472. glintInfo->regs.GammaMultiGLINTAperture =
  473. TRANSLATE_ADDR(&(pCtrlRegs->GammaMultiGLINTAperture));
  474. // PXRX only bypass stuff:
  475. glintInfo->regs.PXRXByAperture1Mode = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByAperture1Mode) );
  476. glintInfo->regs.PXRXByAperture1Stride = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByAperture1Stride) );
  477. //glintInfo->regs.PXRXByAperture1YStart
  478. //glintInfo->regs.PXRXByAperture1UStart
  479. //glintInfo->regs.PXRXByAperture1VStart
  480. glintInfo->regs.PXRXByAperture2Mode = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByAperture2Mode) );
  481. glintInfo->regs.PXRXByAperture2Stride = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByAperture2Stride) );
  482. //glintInfo->regs.PXRXByAperture2YStart
  483. //glintInfo->regs.PXRXByAperture2UStart
  484. //glintInfo->regs.PXRXByAperture2VStart
  485. glintInfo->regs.PXRXByDMAReadMode = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByDMAReadMode) );
  486. glintInfo->regs.PXRXByDMAReadStride = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByDMAReadStride) );
  487. //glintInfo->regs.PXRXByDMAReadYStart
  488. //glintInfo->regs.PXRXByDMAReadUStart
  489. //glintInfo->regs.PXRXByDMAReadVStart
  490. glintInfo->regs.PXRXByDMAReadCommandBase = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByDMAReadCommandBase) );
  491. glintInfo->regs.PXRXByDMAReadCommandCount = TRANSLATE_ADDR( &(pCtrlRegs->PXRXByDMAReadCommandCount) );
  492. //glintInfo->regs.PXRXByDMAWriteMode
  493. //glintInfo->regs.PXRXByDMAWriteStride
  494. //glintInfo->regs.PXRXByDMAWriteYStart
  495. //glintInfo->regs.PXRXByDMAWriteUStart
  496. //glintInfo->regs.PXRXByDMAWriteVStart
  497. //glintInfo->regs.PXRXByDMAWriteCommandBase
  498. //glintInfo->regs.PXRXByDMAWriteCommandCount
  499. // Debug/profile registers on a P3.
  500. glintInfo->regs.TestOutputRdy = TRANSLATE_ADDR( &(pCtrlRegs->TestOutputRdy) );
  501. glintInfo->regs.TestInputRdy = TRANSLATE_ADDR( &(pCtrlRegs->TestInputRdy) );
  502. glintInfo->regs.LocalMemProfileMask0 = TRANSLATE_ADDR( &(pCtrlRegs->LocalMemProfileMask0) );
  503. glintInfo->regs.LocalMemProfileMask1 = TRANSLATE_ADDR( &(pCtrlRegs->LocalMemProfileMask1) );
  504. glintInfo->regs.LocalMemProfileCount0 = TRANSLATE_ADDR( &(pCtrlRegs->LocalMemProfileCount0) );
  505. glintInfo->regs.LocalMemProfileCount1 = TRANSLATE_ADDR( &(pCtrlRegs->BootAddress) );
  506. // initialize the overlay to be disabled
  507. glintInfo->OverlayMode = GLINT_DISABLE_OVERLAY;
  508. glintInfo->WriteMask = 0xffffffff;
  509. glintInfo->DefaultWriteMask = 0xffffffff;
  510. //@@BEGIN_DDKSPLIT
  511. // TMM: On ELSA Gloria Gamma boards with 640 RAMDACs at 15BPP, bit 15 is used
  512. // by the RAMDAC to select a different LUT. So we have to mask
  513. // the top bit out when writing to the framebuffer.
  514. //@@END_DDKSPLIT
  515. if (glintInfo->deviceInfo.ActualDacId == RGB640_RAMDAC &&
  516. ppdev->cPelSize == GLINTDEPTH16)
  517. {
  518. glintInfo->DefaultWriteMask = 0x7FFF7FFF;
  519. glintInfo->WriteMask = 0x7FFF7FFF;
  520. }
  521. // Initialise current FIFO count
  522. glintInfo->FifoCnt = 0;
  523. //@@BEGIN_DDKSPLIT
  524. #if 0 // HIDEYUKN
  525. //
  526. // If we have a gamma ramp saved in the registry then use that. Otherwise,
  527. // initialize the LUT with a gamma of 1.0
  528. //
  529. if (!bGlintRegistryRetrieveGammaLUT(ppdev, &glintInfo->gammaLUT) ||
  530. !bInstallGammaLUT(ppdev, &glintInfo->gammaLUT, FALSE))
  531. {
  532. vSetNewGammaValue(ppdev, 0x10000, FALSE);
  533. }
  534. #endif
  535. //@@END_DDKSPLIT
  536. //
  537. // initialize our DMA buffers if any are configured
  538. //
  539. vGlintInitializeDMA(ppdev);
  540. // fill in the glintInfo capability flags and block fill size.
  541. //
  542. glintInfo->flags |= GLICAP_NT_CONFORMANT_LINES;
  543. glintInfo->fastFillSupport = 0;
  544. glintInfo->renderFastFill = 0;
  545. glintInfo->fastFillBlockSz = 0;
  546. {
  547. ULONG DMAMemoryControl = 0;
  548. DMAMemoryControl |= 1 << 2; // align host-in DMA to 64 bit boundaries
  549. DMAMemoryControl |= (0 & 0x1f) << 24; // burst size n == (1 << 7+n)? Spec indicates n * 128
  550. DMAMemoryControl |= 1 << 31; // align host-out DMA to 64 bit boundaries
  551. if( ppdev->flCaps & CAPS_USE_AGP_DMA )
  552. DMAMemoryControl |= 1 << 0; // host-in DMA uses AGP
  553. WAIT_GLINT_FIFO(1);
  554. LD_GLINT_FIFO(__GlintTagDMAMemoryControl, DMAMemoryControl);
  555. }
  556. {
  557. ULONG *dmaVirt = glintInfo->PXRXDMABuffer.virtAddr;
  558. ULONG dmaPhys = (ULONG) glintInfo->PXRXDMABuffer.physAddr.LowPart;
  559. ULONG size = (glintInfo->PXRXDMABuffer.size) / sizeof(ULONG);
  560. DISPDBG((DBGLVL, "PXRX_DMA: allocated: 0x%08X + 0x%08X @ 0x%08X",
  561. glintInfo->PXRXDMABuffer.virtAddr, glintInfo->PXRXDMABuffer.size, glintInfo->PXRXDMABuffer.physAddr));
  562. if ((glintInfo->PXRXDMABuffer.virtAddr == 0) ||
  563. (glintInfo->PXRXDMABuffer.size == 0 ) ||
  564. (glintInfo->PXRXDMABuffer.physAddr.LowPart == 0))
  565. {
  566. DISPDBG((DBGLVL, "PXRX_DMA: Physical buffer allocation has failed, using a virtual buffer..."));
  567. size = 256 * 1024;
  568. dmaVirt = (ULONG *) ENGALLOCMEM(FL_ZERO_MEMORY,
  569. size * sizeof(ULONG),
  570. ALLOC_TAG_GDI(B));
  571. if (NULL == dmaVirt)
  572. {
  573. DISPDBG((-1, "FATAL ERROR: DRIVER REQUIRES DMA BUFFER FOR 2D - UNLOADING DRIVER"));
  574. return(FALSE);
  575. }
  576. glintInfo->PXRXDMABuffer.size = size;
  577. glintInfo->PXRXDMABuffer.virtAddr = dmaVirt;
  578. glintInfo->PXRXDMABuffer.physAddr.LowPart = 0;
  579. glintInfo->PXRXDMABuffer.physAddr.HighPart = 0;
  580. glintInfo->usePXRXdma = USE_PXRX_DMA_FIFO;
  581. pxrxSetupFunctionPointers( ppdev );
  582. }
  583. ASSERTDD( glintInfo->PXRXDMABuffer.virtAddr != 0, "PXRX_DMA: The buffer has no virtual address!" );
  584. ASSERTDD( glintInfo->PXRXDMABuffer.size != 0, "PXRX_DMA: The buffer has a zero size!" );
  585. # if PXRX_DMA_BUFFER_CHECK
  586. {
  587. ULONG protSize = PXRX_DMA_BUFFER_CHECK_SIZE;
  588. ULONG buffSize = (size - (protSize * 3)) / 2;
  589. ULONG *ptr;
  590. /*
  591. 0k - 16k = 16k = protection zone 0
  592. 16k - 56k = (size - (16 * 3)) / 2 = buffer 0
  593. 56k - 72k = 16k = protection zone 1
  594. 72k - 112k = (size - (16 * 3)) / 2 = buffer 1
  595. 112k - 128k = 16k = protection zone 2
  596. */
  597. glintInfo->pxrxDMA_bufferBase = dmaVirt;
  598. glintInfo->pxrxDMA_bufferTop = &dmaVirt[size];
  599. gi_pxrxDMA.DMAaddrL[0] = &dmaVirt[protSize];
  600. gi_pxrxDMA.DMAaddrEndL[0] = gi_pxrxDMA.DMAaddrL[0] + buffSize;
  601. gi_pxrxDMA.DMAaddrL[1] = gi_pxrxDMA.DMAaddrEndL[0] + protSize;
  602. gi_pxrxDMA.DMAaddrEndL[1] = gi_pxrxDMA.DMAaddrL[1] + buffSize;
  603. for( ptr = dmaVirt; ptr < glintInfo->pxrxDMA_bufferTop; ptr++ )
  604. *ptr = (ULONG)(((ULONG_PTR) ptr) & 0x0FFFFFF0);
  605. DISPDBG((DBGLVL, "PXRX_DMA: prot 0 = 0x%08X -> 0x%08X", glintInfo->pxrxDMA_bufferBase, gi_pxrxDMA.DMAaddrL[0]));
  606. DISPDBG((DBGLVL, "PXRX_DMA: buffer 0 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrL[0], gi_pxrxDMA.DMAaddrEndL[0]));
  607. DISPDBG((DBGLVL, "PXRX_DMA: prot 1 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrEndL[0], gi_pxrxDMA.DMAaddrL[1]));
  608. DISPDBG((DBGLVL, "PXRX_DMA: buffer 1 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrL[1], gi_pxrxDMA.DMAaddrEndL[1]));
  609. DISPDBG((DBGLVL, "PXRX_DMA: prot 2 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrEndL[1], glintInfo->pxrxDMA_bufferTop));
  610. }
  611. # else // PXRX_DMA_BUFFER_CHECK
  612. gi_pxrxDMA.DMAaddrL[0] = dmaVirt;
  613. gi_pxrxDMA.DMAaddrL[1] = &dmaVirt[ size / 2 ];
  614. gi_pxrxDMA.DMAaddrEndL[0] = &dmaVirt[(size / 2) - 1];
  615. gi_pxrxDMA.DMAaddrEndL[1] = &dmaVirt[ size - 1];
  616. # endif // PXRX_DMA_BUFFER_CHECK
  617. gi_pxrxDMA.NTbuff = 0;
  618. gi_pxrxDMA.NTptr = gi_pxrxDMA.DMAaddrL[gi_pxrxDMA.NTbuff];
  619. gi_pxrxDMA.NTdone = gi_pxrxDMA.NTptr;
  620. gi_pxrxDMA.P3at = gi_pxrxDMA.NTptr;
  621. #if PXRX_DMA_BUFFER_CHECK
  622. glintInfo->NTwait = gi_pxrxDMA.NTptr;
  623. #endif
  624. gi_pxrxDMA.DMAaddrP[0] = dmaPhys + (DWORD)((UINT_PTR) gi_pxrxDMA.DMAaddrL[0] - (UINT_PTR) dmaVirt);
  625. gi_pxrxDMA.DMAaddrP[1] = dmaPhys + (DWORD)((UINT_PTR) gi_pxrxDMA.DMAaddrL[1] - (UINT_PTR) dmaVirt);
  626. gi_pxrxDMA.DMAaddrEndP[0] = dmaPhys + (DWORD)((UINT_PTR) gi_pxrxDMA.DMAaddrEndL[0] - (UINT_PTR) dmaVirt);
  627. gi_pxrxDMA.DMAaddrEndP[1] = dmaPhys + (DWORD)((UINT_PTR) gi_pxrxDMA.DMAaddrEndL[1] - (UINT_PTR) dmaVirt);
  628. DISPDBG((DBGLVL, "PXRX_DMA: buffer 0 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrL[0], gi_pxrxDMA.DMAaddrEndL[0]));
  629. DISPDBG((DBGLVL, "PXRX_DMA: buffer 1 = 0x%08X -> 0x%08X", gi_pxrxDMA.DMAaddrL[1], gi_pxrxDMA.DMAaddrEndL[1]));
  630. #if PXRX_DMA_BUFFER_CHECK
  631. {
  632. extern ULONG inPxRxContextSwitch;
  633. inPxRxContextSwitch = TRUE;
  634. CHECK_PXRX_DMA_VALIDITY( CHECK_SWITCH, 0 );
  635. inPxRxContextSwitch = FALSE;
  636. }
  637. #endif
  638. }
  639. // Allocate a GLINT context for this PDEV. Save the current context
  640. // if any and make us the current one but do this by hand since our
  641. // software copy will be junk if this is the very first PDEV.
  642. //
  643. DISPDBG((DBGLVL, "allocating new context"));
  644. // Create the 2D context:
  645. glintInfo->ddCtxtId = GlintAllocateNewContext(ppdev,
  646. (ULONG *) pxrxRestore2DContext,
  647. 0, 0, NULL, ContextType_Fixed);
  648. if (glintInfo->ddCtxtId < 0)
  649. {
  650. DISPDBG((ERRLVL, "failed to allocate GLINT context for display driver"));
  651. return(FALSE);
  652. }
  653. DISPDBG((DBGLVL, "got context id 0x%x", glintInfo->ddCtxtId));
  654. GLINT_VALIDATE_CONTEXT(-1);
  655. ppdev->currentCtxt = glintInfo->ddCtxtId;
  656. DISPDBG((DBGLVL, "context id 0x%x is now current", glintInfo->ddCtxtId));
  657. if (ppdev->flCaps & CAPS_QUEUED_DMA)
  658. {
  659. DISPDBG((DBGLVL, "Enabling queued DMA for Gamma - initializing control regs"));
  660. READ_GLINT_CTRL_REG(GammaCommandMode, ulValue);
  661. ulValue |= GAMMA_COMMAND_MODE_QUEUED_DMA;
  662. WRITE_GLINT_CTRL_REG(GammaCommandMode, ulValue);
  663. }
  664. if( GLINT_GAMMA_PRESENT )
  665. {
  666. //
  667. // The disconnect should be setup correctly in the miniport.
  668. //
  669. glintInfo->PCIDiscEnabled = FALSE;
  670. } else {
  671. // Configure PCI disconnect
  672. //
  673. if (ppdev->cPelSize == GLINTDEPTH32)
  674. {
  675. glintInfo->PCIDiscEnabled = FALSE;
  676. }
  677. else
  678. {
  679. glintInfo->PCIDiscEnabled = USE_PCI_DISC_PERM;
  680. }
  681. // Enable/Disable PCI disconnect as required
  682. WRITE_GLINT_CTRL_REG(DisconnectControl,
  683. (glintInfo->PCIDiscEnabled ? DISCONNECT_INPUT_FIFO_ENABLE :
  684. DISCONNECT_INOUT_DISABLE));
  685. }
  686. // We only want to check the FIFO if disconnect is disabled.
  687. glintInfo->CheckFIFO = !glintInfo->PCIDiscEnabled;
  688. // Setup DMA control on GMX or PXRX
  689. {
  690. ULONG DMAControl = DMA_CONTROL_USE_PCI;
  691. if (!(ppdev->flCaps & CAPS_USE_AGP_DMA))
  692. {
  693. DMAControl = DMA_CONTROL_USE_PCI; // AGP not enabled use PCI master DMA
  694. }
  695. else
  696. {
  697. DMAControl = 2; // PXRX: use AGP master DMA
  698. // When using AGP SideBandAddressing, the following tweak should be a performance gain
  699. WRITE_GLINT_CTRL_REG (AGPControl, AGP_LONG_READ_DISABLE );
  700. }
  701. // Write DMA control
  702. WRITE_GLINT_CTRL_REG (DMAControl, DMAControl);
  703. }
  704. // there are many mode registers we never use so we must disable them.
  705. //
  706. vInitCoreRegisters(ppdev);
  707. ulValue = 32;
  708. DISPDBG((DBGLVL, "Using block fill of width %d pixels", ulValue));
  709. glintInfo->fastFillBlockSz = ulValue;
  710. glintInfo->fastFillSupport = __RENDER_FAST_FILL_INC(ulValue);
  711. glintInfo->renderFastFill = __RENDER_FAST_FILL_ENABLE |
  712. __RENDER_FAST_FILL_INC(ulValue);
  713. // On a Geo Twin we disable the pointer cache and brush cache.
  714. // and on a delta-based Geo Twin we disable off-screen bitmaps too,
  715. // because they slow things down.
  716. if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
  717. {
  718. // Gamma boards can have off-screen bitmaps, because Gamma has
  719. // something called the multi-glint aperture.
  720. if (GLINT_DELTA_PRESENT)
  721. ppdev->flStatus &= ~(STAT_DEV_BITMAPS | ENABLE_DEV_BITMAPS);
  722. //@@BEGIN_DDKSPLIT
  723. // ppdev->flStatus &= ~(ENABLE_POINTER_CACHE);
  724. // ppdev->flStatus &= ~(ENABLE_BRUSH_CACHE);
  725. // ppdev->flStatus &= ~(ENABLE_GLYPH_CACHE);
  726. //@@END_DDKSPLIT
  727. }
  728. // initially assume that we do not have an off-screen buffer for
  729. // bitblt and full screen double buffering. So set all buffer offsets
  730. // to zero. This may get overriden when we init the off-screen heap.
  731. //
  732. for (i = 0; i < GLINT_NUM_SCREEN_BUFFERS; ++i)
  733. {
  734. glintInfo->bufferOffset[i] = 0;
  735. glintInfo->bufferRow[i] = 0;
  736. }
  737. // Initialise back-buffer POH
  738. glintInfo->backBufferPoh = NULL;
  739. glintInfo->GMX2KLastLine = 0;
  740. // Work out our double buffering requirements. First read the registry to
  741. // find out if we need an off-screen buffer. If not then we have nothing
  742. // to do. We want an off-screen buffer if the string exists and the
  743. // buffer count is >= 2. For the moment values > 2 mean use two buffers.
  744. // i.e. we don't support triple or quad buffering etc.
  745. // Note, for GLINT we assume that the extra buffer always lives
  746. // below the visible buffer (i.e. not to the right).
  747. // If the variable doesn't exist, assume 2 buffers.
  748. //
  749. bCreateBackBuffer = FALSE;
  750. bCreateStereoBuffers = FALSE;
  751. bExists = bGlintQueryRegistryValueUlong(ppdev,
  752. REG_NUMBER_OF_SCREEN_BUFFERS,
  753. &ulValue);
  754. if (!bExists)
  755. {
  756. ulValue = 2;
  757. }
  758. if ((ulValue >= 2) && (ppdev->cyMemory >= (ppdev->cyScreen << 1)))
  759. {
  760. //@@BEGIN_DDKSPLIT
  761. //ULONG ulValue;
  762. LONG leftOffset;
  763. LONG byteTotal;
  764. LONG lTotal;
  765. ULONG rowSz;
  766. // if (GLINT_PXRX) // ???
  767. if (1)
  768. {
  769. #if 0
  770. // if we have enough SGRAM then we can support both BLT and
  771. // full screen double buffering.
  772. glintInfo->flags |= GLICAP_BITBLT_DBL_BUF |
  773. GLICAP_FULL_SCREEN_DBL_BUF;
  774. cx = ppdev->cxMemory;
  775. cy = ppdev->cyScreen;
  776. lTotal = cx * cy;
  777. rowSz = 1;
  778. leftOffset = 0;
  779. #else
  780. //@@END_DDKSPLIT
  781. bCreateBackBuffer = TRUE;
  782. //@@BEGIN_DDKSPLIT
  783. goto ConfigurePermediaBuffers;
  784. #endif
  785. }
  786. else
  787. {
  788. // we have enough VRAM so we at least support BLT double buffering
  789. glintInfo->flags |= GLICAP_BITBLT_DBL_BUF;
  790. // read FBModeSel to get the interleave etc. We're only interested in
  791. // whether we are up to 2-way or 4-way, so the left shift is adequate.
  792. // i.e. I don't care that (0 << 1) is "zero-way" rather than 1-way.
  793. //
  794. cx = ppdev->cxMemory;
  795. cy = ppdev->cyScreen;
  796. lTotal = cx * cy;
  797. //@@BEGIN_DDKSPLIT
  798. // AZN This code was originally not being used
  799. #if 0
  800. if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
  801. {
  802. OH *pohTmp;
  803. ULONG NumpadLines;
  804. LONG halfWay = ppdev->FrameBufferLength >> 1; // TMM: This was FOUR_MB
  805. NumpadLines = ((halfWay / ppdev->lDelta) - ppdev->cyScreen; & ~1;
  806. DISPDBG((DBGLVL, "Allocating padding bitmap of size %d x %d",
  807. cx, NumpadLines));
  808. pohTmp = pohAllocate(ppdev, NULL, cx, NumpadLines, 0);
  809. ASSERTDD(pohTmp != NULL, "pad buffer could not be allocated");
  810. // now allocate the actual back buffer
  811. cy = ((((halfWay + ppdev->lDelta - 1) / ppdev->lDelta) - NumpadLines) + 1) & ~1;
  812. DISPDBG((DBGLVL, "Allocating Racer back buffer of size %d x %d", cx, cy));
  813. poh = pohAllocate(ppdev, NULL, cx, cy, FLOH_MAKE_PERMANENT);
  814. ASSERTDD((poh != NULL) && (poh->x == 0) && (poh->y == (halfWay / ppdev->lDelta)),
  815. "Racer off-screen buffer allocated in incorrect position");
  816. DISPDBG((DBGLVL, "Racer back buffer at %d, %d", poh->x, poh->y));
  817. // as far as the 3D ext is concerned, the buffer lives at the
  818. // pixel address of the half-way boundary, but the VTGFrameRowAddr
  819. // is zero. We will examine the (GLICAP_RACER_BANK_SELECT |
  820. // GLICAP_ENHANCED_TX_BANK_SELECT) bits at swap time to see which
  821. // register we should load.
  822. //
  823. glintInfo->bufferOffset[1] = halfWay >> ppdev->cPelSize;
  824. glintInfo->bufferRow[1] = 0;
  825. DISPDBG((DBGLVL, "Racer offscreen buffer at offset 0x%x", GLINT_BUFFER_OFFSET(1)));
  826. // release the temporary buffer. We can use this as off-screen
  827. // memory.
  828. pohFree(ppdev, pohTmp);
  829. }
  830. #endif
  831. //@@END_DDKSPLIT
  832. // now see if we can handle full screen double buffering. This has
  833. // a slightly more stringent requirement because the second buffer
  834. // must start on a VRAM RAS line. OK, here's the equation for the
  835. // number of pixels per RAS line:
  836. // 512 * interleave_size * width_in_dwords * pixels_per_dword
  837. // The only dodgy number here is 512 but I am assured that all
  838. // the VRAMs that GLINT supports have this shift register size.
  839. //
  840. READ_GLINT_CTRL_REG (FBModeSel, ulValue);
  841. DISPDBG((DBGLVL, "FBModeSel = 0x%x", ulValue));
  842. rowSz = 512 << ((ulValue & 1) + // width in dwords
  843. ((ulValue >> 8) & 3) + // interleave value
  844. (2 - ppdev->cPelSize)); // pixels per dword
  845. DISPDBG((DBGLVL, "got FrameRow of size 0x%x pixels", rowSz));
  846. // we have the RAS line size, so we must ensure that the second
  847. // buffer starts at a multiple of this many pixels from the
  848. // origin. This may not be zero in x since the screen stride may
  849. // not be a multiple of this number. So we calculate the number
  850. // of extra scanlines we need to span a full buffer that starts
  851. // on a RAS line boundary. Note, we know that rowSz is a
  852. // power of 2 so we can subtract 1 to get a mod mask.
  853. //
  854. leftOffset = (ULONG)(-lTotal) & (rowSz - 1);
  855. cy += (leftOffset + (cx-1)) / cx;
  856. // cx and cy are now the dimensions of the off-screen buffer we
  857. // want, including the extra scanlines needed to align the full
  858. // screen buffer. Since cy may have increased, again check we
  859. // have enough VRAM. If not then the full-screen alignment will
  860. // have caused us to run over the end. In this case we can position
  861. // the off-screen buffer immediately after the screen but we can't
  862. // offset into it the number of pixels required to align a
  863. // full-screen double buffer.
  864. //
  865. if ((ppdev->cyScreen + cy) <= ppdev->cyMemory)
  866. {
  867. // We can use VTGRowAddress if:
  868. // we don't cross a 4MB boundary or
  869. // (we have an interleave factor of 4 and we don't have an Omnicomp 3Demon Pro16)
  870. // else we can use Racer bank select if we have a Racer board.
  871. //
  872. if ((glintInfo->deviceInfo.BoardId == GLINT_RACER) ||
  873. (glintInfo->deviceInfo.BoardId == GLINT_RACER_PRO) ||
  874. (glintInfo->deviceInfo.BoardId == OMNICOMP_3DEMONPRO) ||
  875. (glintInfo->deviceInfo.BoardId == GEO_TWIN_BOARD) ||
  876. (glintInfo->deviceInfo.BoardId == ACCELPRO_BOARD) ||
  877. (glintInfo->deviceInfo.BoardId == ELSA_GLORIA_XL) ||
  878. (glintInfo->deviceInfo.BoardId == ELSA_GLORIA))
  879. {
  880. glintInfo->flags |= GLICAP_FULL_SCREEN_DBL_BUF |
  881. GLICAP_RACER_DOUBLE_WRITE;
  882. // The 3Demon Pro16 board does not support, enhanced
  883. // mode bank-switching.
  884. if ((ppdev->flCaps & CAPS_ENHANCED_TX) &&
  885. (!IS_RACER_VARIANT_PRO16(ppdev)))
  886. {
  887. DISPDBG((DBGLVL, "Enhanced TX full-screen buffering"));
  888. glintInfo->flags |= GLICAP_ENHANCED_TX_BANK_SELECT;
  889. }
  890. else
  891. {
  892. DISPDBG((DBGLVL, "Racer bank select full-screen buffering"));
  893. glintInfo->flags |= GLICAP_RACER_BANK_SELECT;
  894. }
  895. }
  896. else if (((ppdev->cyScreen + cy) * ppdev->lDelta <= FOUR_MB) ||
  897. ((!IS_RACER_VARIANT_PRO16(ppdev))))
  898. {
  899. DISPDBG((DBGLVL, "VTGFrameRowAddress full-screen buffering"));
  900. glintInfo->flags |= GLICAP_FULL_SCREEN_DBL_BUF;
  901. }
  902. }
  903. else
  904. cy = ppdev->cyScreen;
  905. }
  906. if (glintInfo->flags & (GLICAP_RACER_BANK_SELECT |
  907. GLICAP_ENHANCED_TX_BANK_SELECT))
  908. {
  909. // The second buffer must start in the second half of the frame
  910. // buffer (i.e. at 4MB for an 8MB card and 8MB for a 16MB card) so
  911. // allocate enough off-screen heap to pad up to the scanline
  912. // before this boundary. Then we allocate enough lines so that
  913. // we can move the buffer start to 4MB.
  914. //
  915. OH *pohTmp;
  916. ULONG padLines;
  917. LONG halfWay = ppdev->FrameBufferLength >> 1; // This was FOUR_MB
  918. LONG lScreenDelta;
  919. lScreenDelta = ppdev->lDelta;
  920. padLines = (halfWay / lScreenDelta) - ppdev->cyScreen;
  921. if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
  922. padLines &= ~1; // make number of pad lines even
  923. DISPDBG((DBGLVL, "Allocating padding bitmap of size %d x %d", ppdev->cxScreen, padLines));
  924. pohTmp = pohAllocate(ppdev, NULL, ppdev->cxScreen, padLines, 0);
  925. ASSERTDD(pohTmp != NULL, "pad buffer could not be allocated");
  926. DISPDBG((DBGLVL, "Racer padding bitmap at %d, %d", pohTmp->x, pohTmp->y));
  927. // now allocate the actual back buffer
  928. cy = ((halfWay + lScreenDelta - 1) / lScreenDelta) - padLines;
  929. if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
  930. cy = (cy + 1) & ~1; // round up to make even
  931. DISPDBG((DBGLVL, "Allocating Racer back buffer of size %d x %d", ppdev->cxScreen, cy));
  932. poh = pohAllocate(ppdev, NULL, ppdev->cxScreen, cy, FLOH_MAKE_PERMANENT);
  933. if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER) {
  934. ASSERTDD((poh != NULL) && (poh->x == 0) && (poh->y <= (halfWay / lScreenDelta)) && (poh->y >= ((halfWay / lScreenDelta) - 1)),
  935. "Racer back buffer allocated in incorrect position");
  936. } else {
  937. ASSERTDD((poh != NULL) && (poh->x == 0) && (poh->y == (halfWay / lScreenDelta)),
  938. "Racer back buffer allocated in incorrect position");
  939. }
  940. DISPDBG((DBGLVL, "Racer back buffer at %d, %d", poh->x, poh->y));
  941. // as far as the 3D ext is concerned, the buffer lives at the
  942. // pixel address of the half-way boundary, but the VTGFrameRowAddr
  943. // is zero. We will examine the (GLICAP_RACER_BANK_SELECT |
  944. // GLICAP_ENHANCED_TX_BANK_SELECT) bits at swap time to see which
  945. // register we should load.
  946. //
  947. glintInfo->bufferOffset[1] = halfWay >> ppdev->cPelSize;
  948. if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER)
  949. glintInfo->bufferOffset[1] >>= 1;
  950. glintInfo->bufferRow[1] = 0;
  951. DISPDBG((DBGLVL, "Racer offscreen buffer at offset 0x%x", GLINT_BUFFER_OFFSET(1)));
  952. // Save the back-buffer POH
  953. glintInfo->backBufferPoh = poh;
  954. // release the temporary buffer. We can use this as off-screen
  955. // memory.
  956. pohFree(ppdev, pohTmp);
  957. if (cy > ppdev->cyScreen)
  958. {
  959. POINTL ptl;
  960. OH * pohtmptmp;
  961. LONG lpadLines;
  962. // Calculate padding, ensuring on a Geo we always allocate an
  963. // even number
  964. lpadLines = (cy - ppdev->cyScreen) + 1;
  965. if (ppdev->flCaps & CAPS_SPLIT_FRAMEBUFFER && (lpadLines & 0x1))
  966. lpadLines++;
  967. ptl.x = 0; // Allocate strip directly after the front buffer
  968. ptl.y = ppdev->cyScreen;
  969. pohtmptmp = pohAllocate (ppdev, &ptl, ppdev->cxScreen, lpadLines, FLOH_MAKE_PERMANENT);
  970. ASSERTDD (pohtmptmp, "16BPP Pad buffer alloc failed");
  971. }
  972. }
  973. else
  974. {
  975. // Allocate the off-screen buffer. When we get it back, its
  976. // position should be immediately below the visible screen.
  977. // Since we have checked that we have enough VRAM and GLINT
  978. // never has off-screen memory to the right, it will fail only
  979. // if we get our logic mixed up. e.g. if the initialization
  980. // routines were re-ordered so that the brush cache got called
  981. // before this routine.
  982. //
  983. poh = pohAllocate(ppdev, NULL, cx, cy, FLOH_MAKE_PERMANENT);
  984. ASSERTDD((poh != NULL) && (poh->x == 0) && (poh->y == ppdev->cyScreen),
  985. "off-screen buffer allocated in incorrect position");
  986. DISPDBG((DBGLVL, "allocated off-screen buffer at (%d,%d), w %d h %d",
  987. poh->x, poh->y, poh->cx, poh->cy));
  988. glintInfo->bufferOffset[1] = lTotal;
  989. if (GLINT_FS_DBL_BUF)
  990. {
  991. glintInfo->bufferOffset[1] += leftOffset;
  992. glintInfo->bufferRow[1] = (lTotal + leftOffset) / rowSz;
  993. ASSERTDD(GLINT_BUFFER_OFFSET(1)%rowSz == 0, "off-screen buffer origin not on RAS line");
  994. }
  995. else
  996. leftOffset = 0;
  997. DISPDBG((DBGLVL, "offscreen buffer at offset 0x%x", GLINT_BUFFER_OFFSET(1)));
  998. }
  999. #ifdef LATER
  1000. // We want to create a DIB and surface for the off-screen bitmap.
  1001. // However, the bitmap must start at the correct origin. i.e. if
  1002. // we had to offset the origin to match the VRAM page size (for
  1003. // full screen double buffering) we must move the origin in the
  1004. // poh. Since the node is allocated permanently we don't have to
  1005. // worry about changing poh->x and poh->y. Famous last words?
  1006. //
  1007. if (leftOffset > 0)
  1008. {
  1009. poh->x += leftOffset % ppdev->cxMemory;
  1010. poh->y += leftOffset / ppdev->cxMemory;
  1011. }
  1012. // allocate our DSURF object for the off-screen buffer.
  1013. //
  1014. pdsurf = ENGALLOCMEM(FL_ZERO_MEMORY,
  1015. sizeof(DSURF),
  1016. ALLOC_TAG_GDI(C));
  1017. if (pdsurf == NULL)
  1018. {
  1019. DISPDBG((ERRLVL, "bInitializeGlint - Failed pdsurf allocation"));
  1020. return(FALSE);
  1021. }
  1022. ppdev->pdsurfOffScreen = pdsurf; // Remember it for clean-up
  1023. pdsurf->poh = poh;
  1024. poh->pdsurf = pdsurf;
  1025. pdsurf->dt = DT_SCREEN;
  1026. pdsurf->bOffScreen = TRUE;
  1027. pdsurf->sizl.cx = ppdev->cxScreen; // the poh may be bigger but
  1028. pdsurf->sizl.cy = ppdev->cyScreen; // this is the valid size.
  1029. pdsurf->ppdev = ppdev;
  1030. if (!bCreateScreenDIBForOH(ppdev, poh, HOOK_SYNCHRONIZE))
  1031. {
  1032. DISPDBG((WRNLVL, "bCreateScreenDIBForOH failed for off-screen buffer"));
  1033. return(FALSE);
  1034. }
  1035. if(pdsurf->pso)
  1036. {
  1037. DISPDBG((DBGLVL, "pdsurf->pso for off-screen memory:"));
  1038. DISPDBG((DBGLVL, "DHSURF 0x%x", pdsurf->pso->dhsurf));
  1039. DISPDBG((DBGLVL, "HSURF 0x%x", pdsurf->pso->hsurf));
  1040. DISPDBG((DBGLVL, "DHPDEV 0x%x", pdsurf->pso->dhpdev));
  1041. DISPDBG((DBGLVL, "sizlBitmap %d, %d", pdsurf->pso->sizlBitmap.cx, pdsurf->pso->sizlBitmap.cy));
  1042. DISPDBG((DBGLVL, "cjBits 0x%x", pdsurf->pso->cjBits));
  1043. DISPDBG((DBGLVL, "pvBits 0x%x", pdsurf->pso->pvBits));
  1044. DISPDBG((DBGLVL, "pvScan0 0x%x", pdsurf->pso->pvScan0));
  1045. DISPDBG((DBGLVL, "lDelta %d", pdsurf->pso->lDelta));
  1046. DISPDBG((DBGLVL, "iBitmapFormat 0x%x", pdsurf->pso->iBitmapFormat));
  1047. DISPDBG((DBGLVL, "iType 0x%x", pdsurf->pso->iType));
  1048. DISPDBG((DBGLVL, "fjBitmap 0x%x", pdsurf->pso->fjBitmap));
  1049. }
  1050. #endif // LATER
  1051. //@@END_DDKSPLIT
  1052. }
  1053. //@@BEGIN_DDKSPLIT
  1054. ConfigurePermediaBuffers:
  1055. //@@END_DDKSPLIT
  1056. // Work out the position and sizes for Z buffer and texture memory.
  1057. // For PERMEDIA we need to reserve these with the heap manager since we
  1058. // have a unified memory. For the moment, we will use all the available
  1059. // extra memory for textures. Maybe later make it configurable to allow
  1060. // the 2D driver some off-screen memory.
  1061. // NB. P2 allocates a font cache here, it may be preferable to use the
  1062. // registry to determine the size of the cache
  1063. LOCALBUFFER_PIXEL_WIDTH = 0; // bits
  1064. LOCALBUFFER_PIXEL_OFFSET = 0; // Z pels
  1065. LOCALBUFFER_PIXEL_COUNT = 0; // Z pels
  1066. FONT_MEMORY_OFFSET = 0; // dwords
  1067. FONT_MEMORY_SIZE = 0; // dwords
  1068. TEXTURE_MEMORY_OFFSET = 0; // dwords
  1069. TEXTURE_MEMORY_SIZE = 0; // dwords
  1070. {
  1071. ULONG cjGlyphCache;
  1072. LONG LBPelSize, PatchWidth, PatchRemainder, ZScreenWidth;
  1073. ULONG cyPermanentCaches, cyGlyphCache, cyPointerCache;
  1074. LONG yOrg, ZHeight;
  1075. cjGlyphCache = 300 * 1024;
  1076. //@@BEGIN_DDKSPLIT
  1077. #if 0
  1078. // we don't have a brush cache for these chips
  1079. ppdev->flStatus &= ~ENABLE_BRUSH_CACHE;
  1080. #endif
  1081. //@@END_DDKSPLIT
  1082. // 3D extension fails if we have no textures or Z buffer but still
  1083. // operates without a back buffer. So if we don't have enough
  1084. // memory for Z or textures then abort buffer configuration.
  1085. // (if width=16 => pelsize=1,patchwidth=128)
  1086. LOCALBUFFER_PIXEL_WIDTH = 32;
  1087. LBPelSize = 2;
  1088. PatchWidth = 64;
  1089. DISPDBG((DBGLVL, "bInitializeGlint: P3 Localbuffer width set to %i", LOCALBUFFER_PIXEL_WIDTH ));
  1090. if (ppdev->cPelSize >= LBPelSize)
  1091. {
  1092. ZHeight = ppdev->cyScreen >> (ppdev->cPelSize - LBPelSize);
  1093. }
  1094. else
  1095. {
  1096. ZHeight = ppdev->cyScreen << (LBPelSize - ppdev->cPelSize);
  1097. }
  1098. bCreateBackBuffer = TRUE;
  1099. // Decide if we want to allocate some stereo buffers.
  1100. if(ppdev->flCaps & CAPS_STEREO)
  1101. {
  1102. bCreateStereoBuffers = TRUE;
  1103. }
  1104. cy = ppdev->cyScreen; // front buffer height
  1105. cy += ZHeight; // add on Z buffer height
  1106. cy += TEXTURE_OH_MIN_HEIGHT; // minimum required texture memory
  1107. if (cy > ppdev->cyMemory)
  1108. {
  1109. // Start DirectDraw after the end of the screen
  1110. ppdev->heap.DDrawOffscreenStart = ppdev->cxMemory * ppdev->cyScreen;
  1111. DISPDBG((ERRLVL, "not enough memory for 3D buffers, dd: 0x%x\n", ppdev->heap.DDrawOffscreenStart));
  1112. goto CompletePermediaBuffers;
  1113. }
  1114. // is there room for a back buffer?
  1115. if ((cy + ppdev->cyScreen) > ppdev->cyMemory)
  1116. {
  1117. bCreateBackBuffer = FALSE;
  1118. }
  1119. else if (bCreateBackBuffer)
  1120. {
  1121. cy += ppdev->cyScreen;
  1122. }
  1123. // is there room for stereo buffers?
  1124. if ((cy + (2*ppdev->cyScreen)) > ppdev->cyMemory)
  1125. {
  1126. bCreateStereoBuffers = FALSE;
  1127. }
  1128. else if (bCreateStereoBuffers)
  1129. {
  1130. cy += (2*ppdev->cyScreen);
  1131. }
  1132. // cy is now the total length of all buffers required for 3D.
  1133. // cyPermanentCaches is the combined height of the 2D caches that lie between the front & back buffers
  1134. cyPermanentCaches = 0;
  1135. // yOrg is the start of offscreen memory
  1136. yOrg = ppdev->cyScreen + cyPermanentCaches;
  1137. if (bCreateBackBuffer)
  1138. {
  1139. glintInfo->flags |= GLICAP_BITBLT_DBL_BUF | GLICAP_FULL_SCREEN_DBL_BUF;
  1140. if (glintInfo->pxrxFlags & PXRX_FLAGS_PATCHING_BACK)
  1141. {
  1142. ULONG bb, patchWidth, patchSize, x, y;
  1143. /*
  1144. Align Size cPelSize 2 - cPS 4 - cPS
  1145. 32bpp: 0x100 0x1000 2 0 >> 1 2 >> 4
  1146. 16bpp: 0x 80 0x 800 1 1 >> 2 3 >> 8
  1147. 8bpp: 0x 40 0x 400 0 2 >> 4 4 >> 16
  1148. patchSize = 0x400 << ppdev->cPelSize; // Bytes
  1149. regAlign = 0x40 << ppdev->cPelSize; // 128 bits
  1150. reg = bufferOffset >> (4 - ppdev->cPelSize);
  1151. bufferOffsetAlignment = regAlign << (4 - ppdev->cPelSize); // 1024
  1152. = (0x40 << ppdev->cPelSize) << (4 - ppdev->cPelSize);
  1153. = 0x40 << 4;
  1154. = 1024;
  1155. NB: verticalAlignment = 16 scanlines;
  1156. */
  1157. bb = ((ppdev->cxMemory * yOrg) + 1023) & ~1023;
  1158. if( bb % ppdev->cxMemory )
  1159. bb = (bb / ppdev->cxMemory) + 1;
  1160. else
  1161. bb = bb / ppdev->cxMemory;
  1162. bb = (bb + 15) & ~15;
  1163. bb *= ppdev->cxMemory;
  1164. ppdev->heap.DDrawOffscreenStart = // Save DirectDraw off-screen offset
  1165. glintInfo->bufferRow[1] =
  1166. glintInfo->bufferOffset[1] = bb;
  1167. x = bb % ppdev->cxMemory;
  1168. y = bb / ppdev->cxMemory;
  1169. glintInfo->backBufferXY = (x & 0xFFFF) | (y << 16);
  1170. //LOAD_FBWRITE_OFFSET( 1, glintInfo->backBufferXY );
  1171. yOrg = y + ppdev->cyScreen; // Y origin of next buffer
  1172. }
  1173. else
  1174. {
  1175. ppdev->heap.DDrawOffscreenStart = // Save DirectDraw off-screen offset
  1176. glintInfo->bufferRow[1] =
  1177. glintInfo->bufferOffset[1] = ppdev->cxMemory * yOrg;
  1178. glintInfo->backBufferXY = yOrg << 16;
  1179. //LOAD_FBWRITE_OFFSET( 1, glintInfo->backBufferXY );
  1180. yOrg += ppdev->cyScreen; // Y origin of next buffer
  1181. }
  1182. DISPDBG((DBGLVL, "offscreen buffer at offset 0x%x", GLINT_BUFFER_OFFSET(1)));
  1183. }
  1184. else
  1185. {
  1186. // DirectDraw can use the memory that is left over
  1187. ppdev->heap.DDrawOffscreenStart = ppdev->cxMemory * yOrg;
  1188. DISPDBG((DBGLVL, "No Permedia back buffer being created dd: 0x%x", ppdev->heap.DDrawOffscreenStart));
  1189. }
  1190. // Setup stereo front and back buffers if they're required.
  1191. // We just place them directly after the back buffer.
  1192. // Patching requirements should be satisfied as long as the
  1193. // front and back are patched/unpatched together.
  1194. if (bCreateStereoBuffers)
  1195. {
  1196. // Stereo back buffer
  1197. glintInfo->backRightBufferXY = (glintInfo->backBufferXY + (ppdev->cyScreen << 16));
  1198. glintInfo->bufferRow[2] = glintInfo->bufferOffset[2] =
  1199. (glintInfo->bufferOffset[1] + (ppdev->cxMemory * ppdev->cyScreen));
  1200. // Stereo front buffer
  1201. glintInfo->frontRightBufferXY = glintInfo->backRightBufferXY + (ppdev->cyScreen << 16);
  1202. glintInfo->bufferRow[3] = glintInfo->bufferOffset[3] =
  1203. (glintInfo->bufferOffset[2] + (ppdev->cxMemory * ppdev->cyScreen));
  1204. yOrg += (2*ppdev->cyScreen); // Y origin of next buffer
  1205. // We successfully allocated stereo buffers so set the flag.
  1206. glintInfo->flags |= GLICAP_STEREO_BUFFERS;
  1207. }
  1208. else
  1209. {
  1210. // If we aren't in stereo mode then set the right buffers to their
  1211. // left equivalents.
  1212. glintInfo->frontRightBufferXY = 0;
  1213. glintInfo->backRightBufferXY = glintInfo->backBufferXY;
  1214. glintInfo->bufferRow[2] = glintInfo->bufferOffset[2] = glintInfo->bufferOffset[1];
  1215. glintInfo->bufferRow[3] = glintInfo->bufferOffset[3] = glintInfo->bufferOffset[0];
  1216. }
  1217. {
  1218. // Place the local buffer at end of memory (picks up dedicated page selector).
  1219. // Textures are placed between the back buffer and the local buffer memory.
  1220. // The width of the local buffer is controlled via a registry variable.
  1221. ULONG TopOfLBMemoryDwords ;
  1222. // If the screen width is not a multiple of the patch size then
  1223. // we allocate a slightly larger Z buffer which is.
  1224. if(PatchRemainder = ppdev->cxScreen % PatchWidth)
  1225. {
  1226. ZScreenWidth = ppdev->cxScreen + (PatchWidth - PatchRemainder);
  1227. }
  1228. else
  1229. {
  1230. ZScreenWidth = ppdev->cxScreen;
  1231. }
  1232. // Store the actual Z buffer width
  1233. glintInfo->P3RXLocalBufferWidth = ZScreenWidth;
  1234. LOCALBUFFER_PIXEL_COUNT = ppdev->cyScreen * ZScreenWidth ;
  1235. // LB offset in units of LB pixels
  1236. {
  1237. ULONG TotalMemoryInDwords = (ppdev->cyMemory * ppdev->cxMemory) >> (2 - ppdev->cPelSize) ;
  1238. // Working in unit of LB pixels, and working backwards from the end of memory
  1239. LOCALBUFFER_PIXEL_OFFSET = TotalMemoryInDwords << (2 - LBPelSize) ;
  1240. // Ensure the top left of the last patch starts on a patch boundary
  1241. LOCALBUFFER_PIXEL_OFFSET -= LOCALBUFFER_PIXEL_OFFSET % (PatchWidth*16);
  1242. // Calculate the start of the local buffer memory (used later)
  1243. TopOfLBMemoryDwords = (LOCALBUFFER_PIXEL_OFFSET - LOCALBUFFER_PIXEL_COUNT) >> (2 - LBPelSize) ;
  1244. // Need to subtract one row of patches because origin is at start of
  1245. // last row of patches
  1246. LOCALBUFFER_PIXEL_OFFSET -= (ZScreenWidth*16) ;
  1247. // Add the offset of the bottom left pixel within the bottom left
  1248. // patch.
  1249. LOCALBUFFER_PIXEL_OFFSET += PatchWidth*15;
  1250. }
  1251. DISPDBG((DBGLVL, "bInitializeGlint: P3 cxScreen %i cyScreen %i cPelSize %i", ppdev->cxScreen, ppdev->cyScreen, ppdev->cPelSize));
  1252. DISPDBG((DBGLVL, "bInitializeGlint: P3 cxMemory %i cyMemory %i cPelSize %i", ppdev->cxMemory, ppdev->cyMemory, ppdev->cPelSize));
  1253. DISPDBG((DBGLVL, "bInitializeGlint: P3 LOCALBUFFER_PIXEL_OFFSET %i LOCALBUFFER_PIXEL_COUNT %i ", LOCALBUFFER_PIXEL_OFFSET, LOCALBUFFER_PIXEL_COUNT));
  1254. // Texture memory offset in DWORDS
  1255. TEXTURE_MEMORY_OFFSET = (ppdev->cxMemory * yOrg) >> (2 - ppdev->cPelSize);
  1256. // Texture size calculation
  1257. if (TopOfLBMemoryDwords > TEXTURE_MEMORY_OFFSET)
  1258. {
  1259. TEXTURE_MEMORY_SIZE = TopOfLBMemoryDwords - TEXTURE_MEMORY_OFFSET ;
  1260. }
  1261. else
  1262. {
  1263. TEXTURE_MEMORY_SIZE = 0 ;
  1264. }
  1265. DISPDBG((DBGLVL, "bInitializeGlint: P3 TEXTURE_MEMORY_OFFSET %i", TEXTURE_MEMORY_OFFSET));
  1266. DISPDBG((DBGLVL, "bInitializeGlint: P3 TEXTURE_MEMORY_SIZE in dwords %i", TEXTURE_MEMORY_SIZE));
  1267. }
  1268. # if DBG
  1269. {
  1270. ULONG lbS, lbE, tS, tE;
  1271. 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));
  1272. 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));
  1273. lbS = LOCALBUFFER_PIXEL_OFFSET - (ZScreenWidth * (ppdev->cyScreen - 1));
  1274. lbE = LOCALBUFFER_PIXEL_OFFSET + ZScreenWidth;
  1275. if( ppdev->cPelSize >= LBPelSize ) {
  1276. lbS = lbS >> (ppdev->cPelSize - LBPelSize);
  1277. lbE = lbE >> (ppdev->cPelSize - LBPelSize);
  1278. } else {
  1279. lbS = lbS << (LBPelSize - ppdev->cPelSize);
  1280. lbE = lbE << (LBPelSize - ppdev->cPelSize);
  1281. }
  1282. lbS /= ppdev->cxMemory; lbE /= ppdev->cxMemory;
  1283. DISPDBG((DBGLVL, "bIGlint: local buffer = 0x%08Xp (%4dL) -> 0x%08Xp (%4dL)", LOCALBUFFER_PIXEL_OFFSET - (ZScreenWidth * (ppdev->cyScreen - 1)), lbS, LOCALBUFFER_PIXEL_OFFSET + ZScreenWidth, lbE));
  1284. tS = (TEXTURE_MEMORY_OFFSET << (2 - ppdev->cPelSize)) / ppdev->cxMemory;
  1285. tE = (TEXTURE_MEMORY_SIZE << (2 - ppdev->cPelSize)) / ppdev->cxMemory;
  1286. 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));
  1287. }
  1288. # endif
  1289. }
  1290. CompletePermediaBuffers:
  1291. // work out the fudge factor to add onto VTGVLineNumber to get the current
  1292. // video scanline. VTGVLineNumber returns VTGVLimit for the last visible
  1293. // line on the screen and 1 for line after that. Use the
  1294. // GLINT_GET_VIDEO_SCANLINE macro to retrieve the current scanline.
  1295. //
  1296. READ_GLINT_CTRL_REG (VTGVLimit, glintInfo->vtgvLimit);
  1297. glintInfo->scanFudge = glintInfo->vtgvLimit - ppdev->cyScreen + 1;
  1298. // work out partial products for the screen stride. We need to record
  1299. // the products for 8, 16 and 32 bit width 'pixels', only one is the
  1300. // correct width, but we want to be able to pretend to use 16 and 32
  1301. // bit pixels occasionally on an 8 bit pixel framestore for speed.
  1302. cPelSize = ppdev->cPelSize;
  1303. if(cPelSize == GLINTDEPTH24)
  1304. {
  1305. // 24bpp: special case (3 bytes per pixel)
  1306. width = ppdev->cxMemory * 3;
  1307. }
  1308. else
  1309. {
  1310. width = ppdev->cxMemory << cPelSize; // width of framestore in bytes
  1311. }
  1312. DISPDBG((DBGLVL, "assuming screen stride is %d bytes\n", width));
  1313. // Hardware write mask emulation with DRAMS works for byte masks only
  1314. // I.e. 0xFF00FF00 will work, 0x0FF00FF0 will not.
  1315. READ_GLINT_CTRL_REG( LocalMemCaps, ulValue );
  1316. if (ulValue & (1 << 28))
  1317. {
  1318. glintInfo->flags |= GLICAP_HW_WRITE_MASK_BYTES;
  1319. }
  1320. else
  1321. {
  1322. glintInfo->flags |= GLICAP_HW_WRITE_MASK;
  1323. }
  1324. DISPDBG((DBGLVL, "bInitializeGlint OK"));
  1325. #if DBG
  1326. // print this stuff out for debugging purposes
  1327. if (GLINT_HW_WRITE_MASK)
  1328. DISPDBG((DBGLVL, "Hardware Writemasking enabled"));
  1329. ASSERTDD(!GLINT_CS_DBL_BUF, "Color Space double buffering enabled");
  1330. if (GLINT_FS_DBL_BUF)
  1331. {
  1332. DISPDBG((DBGLVL, "Full screen double buffering enabled"));
  1333. DISPDBG((DBGLVL, "second buffer at pixel offset 0x%x, origin (%d,%d), RowAddr %d",
  1334. GLINT_BUFFER_OFFSET(1),
  1335. GLINT_BUFFER_OFFSET(1) % ppdev->cxMemory,
  1336. GLINT_BUFFER_OFFSET(1) / ppdev->cxMemory,
  1337. glintInfo->bufferRow[1]));
  1338. }
  1339. if (GLINT_BLT_DBL_BUF)
  1340. {
  1341. DISPDBG((DBGLVL, "BITBLT double buffering enabled"));
  1342. DISPDBG((DBGLVL, "second buffer at pixel offset 0x%x, origin (%d,%d)",
  1343. GLINT_BUFFER_OFFSET(1),
  1344. GLINT_BUFFER_OFFSET(1) % ppdev->cxMemory,
  1345. GLINT_BUFFER_OFFSET(1) / ppdev->cxMemory));
  1346. }
  1347. if (GLINT_FAST_FILL_SIZE > 0)
  1348. DISPDBG((DBGLVL, "using fast fill size of %d (%s fast fill bug workarounds)",
  1349. GLINT_FAST_FILL_SIZE, GLINT_FIX_FAST_FILL ? "need" : "don't need"));
  1350. #endif // DBG
  1351. return(TRUE);
  1352. } // bInitializeGlint
  1353. /******************************Public*Routine******************************\
  1354. * VOID vDisableGlint
  1355. *
  1356. * Do whatever we need to when the surface is disabled.
  1357. *
  1358. \**************************************************************************/
  1359. VOID vDisableGlint(PPDEV ppdev)
  1360. {
  1361. DSURF* pdsurf;
  1362. GLINT_DECL;
  1363. if (!glintInfo)
  1364. return;
  1365. if (glintInfo->PXRXDMABuffer.virtAddr && glintInfo->PXRXDMABuffer.physAddr.LowPart == 0)
  1366. {
  1367. DISPDBG((DBGLVL, "DrvDisableSurface: "
  1368. "freeing PXRX virtual DMA buffer %p, size %xh",
  1369. glintInfo->PXRXDMABuffer.virtAddr,
  1370. glintInfo->PXRXDMABuffer.size));
  1371. ENGFREEMEM(glintInfo->PXRXDMABuffer.virtAddr);
  1372. glintInfo->PXRXDMABuffer.virtAddr = NULL;
  1373. glintInfo->PXRXDMABuffer.size = 0;
  1374. }
  1375. // free up any contexts we allocated
  1376. //
  1377. if (glintInfo->ddCtxtId >= 0)
  1378. {
  1379. vGlintFreeContext(ppdev, glintInfo->ddCtxtId);
  1380. }
  1381. //@@BEGIN_DDKSPLIT
  1382. #ifdef LATER
  1383. pdsurf = ppdev->pdsurfOffScreen;
  1384. if (pdsurf != NULL)
  1385. vDeleteScreenDIBFromOH(pdsurf->poh);
  1386. #endif
  1387. //@@END_DDKSPLIT
  1388. // Free GlintInfo and zero it.
  1389. ENGFREEMEM(glintInfo);
  1390. ppdev->glintInfo = NULL;
  1391. } // vDisableGlint
  1392. /******************************Public*Routine******************************\
  1393. * VOID vAssertModeGlint
  1394. *
  1395. * We're about to switch to/from full screen mode so do whatever we need to
  1396. * to save context etc.
  1397. *
  1398. \**************************************************************************/
  1399. VOID vAssertModeGlint(PPDEV ppdev, BOOL bEnable)
  1400. {
  1401. GLINT_DECL;
  1402. if (!glintInfo)
  1403. return;
  1404. if (!bEnable)
  1405. {
  1406. // Reset our software copy of the depth configured for this PDEV
  1407. // back to the native depth. If we don't do this we may end up
  1408. // with the copy and the hardware being out of sync when we
  1409. // re-enable. Also, do a context switch to save our core register
  1410. // state ready for when we get back in. All this forces a SYNC
  1411. // as well which is a good thing.
  1412. //
  1413. VALIDATE_DD_CONTEXT;
  1414. GLINT_DEFAULT_FB_DEPTH;
  1415. GLINT_VALIDATE_CONTEXT(-1);
  1416. }
  1417. else
  1418. {
  1419. // re-enabling our PDEV so reload our context.
  1420. //
  1421. VALIDATE_DD_CONTEXT;
  1422. //@@BEGIN_DDKSPLIT
  1423. #if GAMMA_CORRECTION
  1424. //
  1425. // Restore the current gamma LUT.
  1426. //
  1427. bInstallGammaLUT(ppdev, &glintInfo->gammaLUT, FALSE);
  1428. #endif // GAMMA_CORRECTION
  1429. //@@END_DDKSPLIT
  1430. }
  1431. } // vAssertModeGlint