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.

1469 lines
38 KiB

  1. /******************************Module*Header***********************************\
  2. *
  3. * ****************
  4. * * SAMPLE CODE *
  5. * ****************
  6. *
  7. * Module Name: debug.cpp
  8. *
  9. * Content: Miscellaneous Driver Debug Routines
  10. *
  11. * Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "precomp.h"
  15. #include "gdi.h"
  16. #include "log.h"
  17. LONG DebugLevel = 0; // Set to '100' to debug initialization code
  18. // (the default is '0')
  19. DWORD DebugPrintFilter = 0;
  20. DWORD DebugFilter = 0;
  21. #define ALLOC_TAG ALLOC_TAG_ED2P
  22. //------------------------------------------------------------------------------
  23. //
  24. // VOID DebugPrint
  25. //
  26. // Variable-argument level-sensitive debug print routine.
  27. //
  28. // If the specified debug level for the print statement is lower or equal
  29. // to the current debug level, the message will be printed.
  30. //
  31. // Parameters
  32. // DebugPrintLevel----Specifies at which debugging level the string should
  33. // be printed
  34. // DebugMessage-------Variable argument ascii c string
  35. //
  36. //------------------------------------------------------------------------------
  37. VOID
  38. DebugPrint(
  39. LONG DebugPrintLevel,
  40. PCHAR DebugMessage,
  41. ...
  42. )
  43. {
  44. va_list ap;
  45. va_start(ap, DebugMessage);
  46. if ( ((DebugPrintFilter & DebugFilter) &&
  47. (DebugPrintLevel <= DebugLevel )) ||
  48. DebugPrintLevel <= 0 )
  49. {
  50. EngDebugPrint(STANDARD_DEBUG_PREFIX, DebugMessage, ap);
  51. EngDebugPrint("", "\n", ap);
  52. }
  53. va_end(ap);
  54. } // DebugPrint()
  55. #if DBG
  56. //------------------------------------------------------------------------------
  57. //
  58. // VOID vDumpSurfobj
  59. //
  60. // Dumps using DSPDBG usefull information about the given surface
  61. //
  62. // Parameters
  63. // pso------------surface to dump
  64. //
  65. //------------------------------------------------------------------------------
  66. void
  67. vDumpSurfobj(SURFOBJ* pso)
  68. {
  69. ULONG * bits;
  70. PPDev ppdev;
  71. if(pso != NULL)
  72. {
  73. ULONG width;
  74. ULONG height;
  75. ULONG stride;
  76. ppdev = (PPDev) pso->dhpdev;
  77. if(pso->dhsurf == NULL)
  78. {
  79. bits = (ULONG *) pso->pvScan0;
  80. width = pso->sizlBitmap.cx;
  81. height = pso->sizlBitmap.cy;
  82. stride = pso->lDelta;
  83. DISPDBG((0, "GDI managed surface %lx", pso));
  84. }
  85. else
  86. {
  87. Surf * surf = (Surf *) pso->dhsurf;
  88. if(surf->flags & SF_SM)
  89. {
  90. bits = (ULONG *) surf->pvScan0;
  91. DISPDBG((0, "device managed SM surface %lx", pso));
  92. }
  93. else
  94. {
  95. bits = (ULONG *) (ppdev->pjScreen + surf->ulByteOffset);
  96. DISPDBG((0, "device managed VM surface %lx", pso));
  97. }
  98. width = surf->cx;
  99. height = surf->cy;
  100. stride = surf->lDelta;
  101. }
  102. DISPDBG((0, "width %d height %d", width, height ));
  103. DISPDBG((0, "bits 0x%lx bits[0] 0x%lx stride %ld", bits, bits[0], stride));
  104. }
  105. }
  106. //------------------------------------------------------------------------------
  107. //
  108. // VOID vDumpRect
  109. //
  110. // Dumps the rectangle description using DISPDBG
  111. //
  112. // Parameters
  113. // prcl-----------rectangle to dump
  114. //
  115. //------------------------------------------------------------------------------
  116. void
  117. vDumpRect(RECTL * prcl)
  118. {
  119. if(prcl != NULL)
  120. DISPDBG((0, "left %d top %d width %d height %d",
  121. prcl->left, prcl->top,
  122. prcl->right - prcl->left,
  123. prcl->bottom - prcl->top));
  124. }
  125. //------------------------------------------------------------------------------
  126. //
  127. // VOID vDumpSurfobj
  128. //
  129. // Dumps the point description using DISPDBG
  130. //
  131. // Parameters
  132. // point----------point to dump
  133. //
  134. //------------------------------------------------------------------------------
  135. void
  136. vDumpPoint(POINTL * point)
  137. {
  138. if(point != NULL)
  139. DISPDBG((0, "left %d top %d", point->x, point->y));
  140. }
  141. //------------------------------------------------------------------------------
  142. //
  143. // DEBUGGING INITIALIZATION CODE
  144. //
  145. // When you're bringing up your display for the first time, you can
  146. // recompile with 'DebugLevel' set to 100. That will cause absolutely
  147. // all DISPDBG messages to be displayed on the kernel debugger (this
  148. // is known as the "PrintF Approach to Debugging" and is about the only
  149. // viable method for debugging driver initialization code).
  150. //
  151. //------------------------------------------------------------------------------
  152. //------------------------------------------------------------------------------
  153. //
  154. // THUNK_LAYER
  155. //
  156. // By Setting THUNK_LAYER equal to 1 you are adding a wrapper call on top of
  157. // all DDI rendering functions. In this thunk layer of wrapper calls
  158. // several usefull debugging features are enabled.
  159. //
  160. // Surface checks--which can help catch errant rendering routines
  161. // Event logging---which can record rendering evernts to a log file
  162. //
  163. //------------------------------------------------------------------------------
  164. #if THUNK_LAYER
  165. //------------------------------------------------------------------------------
  166. //
  167. // BOOL bSurfaceChecks
  168. //
  169. // By dynamically setting bSurfaceChecks (via debugger) you can turn
  170. // surface checking on and off. Surface checking is usefull for catching
  171. // errant rendering operations overwritting other surfaces other then the
  172. // destination surface.
  173. //
  174. //------------------------------------------------------------------------------
  175. BOOL bSurfaceChecks = 0;
  176. //------------------------------------------------------------------------------
  177. //
  178. // ULONG ulCalcSurfaceChecksum
  179. //
  180. // Calculates a checksum for the given surface
  181. //
  182. // Parameters
  183. // psurf----Surf to be used for checksum
  184. //
  185. // Retuns checksum for given surface as a ULONG
  186. //
  187. //------------------------------------------------------------------------------
  188. ULONG
  189. ulCalcSurfaceChecksum(Surf* psurf)
  190. {
  191. ULONG ulChecksum = 0;
  192. if( psurf->dt == DT_VM )
  193. {
  194. //
  195. // Get the real memory address of this psurf
  196. //
  197. ULONG* ulp = (ULONG*)(psurf->ppdev->pjScreen + psurf->ulByteOffset);
  198. //
  199. // Get total bytes allocated in this psurf. Here >> 2 is to make
  200. // 4 bytes as a unit so that we can use it to do checksum
  201. //
  202. ULONG ulCount = (psurf->lDelta * psurf->cy) >> 2;
  203. //
  204. // Sum up the contents of all the bytes we allocated
  205. //
  206. while( ulCount-- )
  207. {
  208. ulChecksum += *ulp++;
  209. }
  210. }
  211. return ulChecksum;
  212. }// vCalcSurfaceChecksum()
  213. //------------------------------------------------------------------------------
  214. //
  215. // VOID vCalcSurfaceChecksums
  216. //
  217. // Calculates and stores all surface checksums except for the given destination
  218. // surface.
  219. //
  220. // Parameters
  221. // psoDst---destination SURFOBJ
  222. // psoSrc---source SURFOBJ
  223. //
  224. //------------------------------------------------------------------------------
  225. VOID
  226. vCalcSurfaceChecksums(SURFOBJ * psoDst, SURFOBJ * psoSrc)
  227. {
  228. PPDev ppdev = NULL;
  229. Surf * pdSrcSurf = NULL;
  230. Surf * pdDstSurf = NULL;
  231. ASSERTDD(psoDst != NULL, "unexpected psoDst == NULL");
  232. pdDstSurf = (Surf *) psoDst->dhsurf;
  233. if(psoSrc != NULL)
  234. pdSrcSurf = (Surf *) psoSrc->dhsurf;
  235. if(pdDstSurf != NULL)
  236. ppdev = (PPDev) psoDst->dhpdev;
  237. else if(pdSrcSurf != NULL)
  238. ppdev = (PPDev) psoSrc->dhpdev;
  239. if(ppdev != NULL)
  240. {
  241. Surf * psurf = ppdev->psurfListHead;
  242. while(psurf != ppdev->psurfListTail)
  243. {
  244. if(psurf != pdDstSurf)
  245. psurf->ulChecksum = vCalcSurfaceChecksum(psurf);
  246. psurf = psurf->psurfNext;
  247. }
  248. }
  249. }
  250. //------------------------------------------------------------------------------
  251. //
  252. // VOID vCheckSurfaceChecksums
  253. //
  254. // Calculates and compares all surface checksums except for the given
  255. // destination surface.
  256. //
  257. // Parameters
  258. // psoDst---destination SURFOBJ
  259. // psoSrc---source SURFOBJ
  260. //
  261. //------------------------------------------------------------------------------
  262. VOID
  263. vCheckSurfaceChecksums(SURFOBJ * psoDst, SURFOBJ * psoSrc)
  264. {
  265. PPDev ppdev = NULL;
  266. Surf * pdSrcSurf = NULL;
  267. Surf * pdDstSurf = NULL;
  268. ASSERTDD(psoDst != NULL, "unexpected psoDst == NULL");
  269. pdDstSurf = (Surf *) psoDst->dhsurf;
  270. if(psoSrc != NULL)
  271. pdSrcSurf = (Surf *) psoSrc->dhsurf;
  272. if(pdDstSurf != NULL)
  273. ppdev = (PPDev) psoDst->dhpdev;
  274. else if(pdSrcSurf != NULL)
  275. ppdev = (PPDev) psoSrc->dhpdev;
  276. if(ppdev != NULL)
  277. {
  278. Surf * psurf = ppdev->psurfListHead;
  279. while(psurf != ppdev->psurfListTail)
  280. {
  281. if(psurf != pdDstSurf)
  282. {
  283. ASSERTDD(psurf->ulChecksum == vCalcSurfaceChecksum(psurf),
  284. "unexpected checksum mismatch");
  285. }
  286. psurf = psurf->psurfNext;
  287. }
  288. }
  289. }
  290. //------------------------------------------------------------------------------
  291. // ULONG ulCallDepth
  292. //
  293. // Used for keeping track of how many times the DDI layer has been entered.
  294. // Some punted calls to the GDI engine will cause callbacks into DDI. This
  295. // call depth information is used when event logging.
  296. //
  297. //------------------------------------------------------------------------------
  298. ULONG ulCallDepth = 0;
  299. //------------------------------------------------------------------------------
  300. //
  301. // BOOL xDrvBitBlt
  302. //
  303. // Thunk layer wrapper for DrvBitBlt.
  304. //
  305. //------------------------------------------------------------------------------
  306. BOOL
  307. xDrvBitBlt(SURFOBJ* psoDst,
  308. SURFOBJ* psoSrc,
  309. SURFOBJ* psoMsk,
  310. CLIPOBJ* pco,
  311. XLATEOBJ* pxlo,
  312. RECTL* prclDst,
  313. POINTL* pptlSrc,
  314. POINTL* pptlMsk,
  315. BRUSHOBJ* pbo,
  316. POINTL* pptlBrush,
  317. ROP4 rop4)
  318. {
  319. BOOL bResult;
  320. LONGLONG llStartTicks;
  321. LONGLONG llElapsedTicks;
  322. ulCallDepth++;
  323. if(bSurfaceChecks)
  324. vCalcSurfaceChecksums(psoDst, psoSrc);
  325. EngQueryPerformanceCounter(&llStartTicks);
  326. bResult = DrvBitBlt(psoDst, psoSrc, psoMsk, pco, pxlo, prclDst,
  327. pptlSrc, pptlMsk,pbo, pptlBrush, rop4);
  328. EngQueryPerformanceCounter(&llElapsedTicks);
  329. llElapsedTicks -= llStartTicks;
  330. vLogBitBlt(psoDst, psoSrc, psoMsk, pco, pxlo, prclDst, pptlSrc, pptlMsk,
  331. pbo, pptlBrush, rop4, llElapsedTicks, ulCallDepth);
  332. if(bSurfaceChecks)
  333. vCheckSurfaceChecksums(psoDst, psoSrc);
  334. ulCallDepth--;
  335. return bResult;
  336. }
  337. //------------------------------------------------------------------------------
  338. //
  339. // BOOL xDrvCopyBits
  340. //
  341. // Thunk layer wrapper for DrvCopyBits.
  342. //
  343. //------------------------------------------------------------------------------
  344. BOOL
  345. xDrvCopyBits(
  346. SURFOBJ* psoDst,
  347. SURFOBJ* psoSrc,
  348. CLIPOBJ* pco,
  349. XLATEOBJ* pxlo,
  350. RECTL* prclDst,
  351. POINTL* pptlSrc)
  352. {
  353. BOOL bResult;
  354. LONGLONG llStartTicks;
  355. LONGLONG llElapsedTicks;
  356. ulCallDepth++;
  357. if(bSurfaceChecks)
  358. vCalcSurfaceChecksums(psoDst, psoSrc);
  359. EngQueryPerformanceCounter(&llStartTicks);
  360. bResult = DrvCopyBits(psoDst, psoSrc, pco, pxlo, prclDst, pptlSrc);
  361. EngQueryPerformanceCounter(&llElapsedTicks);
  362. llElapsedTicks -= llStartTicks;
  363. vLogCopyBits(psoDst, psoSrc, pco, pxlo, prclDst, pptlSrc,
  364. llElapsedTicks, ulCallDepth);
  365. if(bSurfaceChecks)
  366. vCheckSurfaceChecksums(psoDst, psoSrc);
  367. ulCallDepth--;
  368. return bResult;
  369. }
  370. //------------------------------------------------------------------------------
  371. //
  372. // BOOL xDrvTransparentBlt
  373. //
  374. // Thunk layer wrapper for DrvTransparentBlt.
  375. //
  376. //------------------------------------------------------------------------------
  377. BOOL
  378. xDrvTransparentBlt(
  379. SURFOBJ * psoDst,
  380. SURFOBJ * psoSrc,
  381. CLIPOBJ * pco,
  382. XLATEOBJ * pxlo,
  383. RECTL * prclDst,
  384. RECTL * prclSrc,
  385. ULONG iTransColor,
  386. ULONG ulReserved)
  387. {
  388. BOOL bResult;
  389. LONGLONG llStartTicks;
  390. LONGLONG llElapsedTicks;
  391. ulCallDepth++;
  392. if(bSurfaceChecks)
  393. vCalcSurfaceChecksums(psoDst, psoSrc);
  394. EngQueryPerformanceCounter(&llStartTicks);
  395. bResult = DrvTransparentBlt(psoDst,
  396. psoSrc,
  397. pco,
  398. pxlo,
  399. prclDst,
  400. prclSrc,
  401. iTransColor,
  402. ulReserved);
  403. EngQueryPerformanceCounter(&llElapsedTicks);
  404. llElapsedTicks -= llStartTicks;
  405. vLogTransparentBlt(psoDst, psoSrc, pco, pxlo, prclDst, prclSrc,
  406. iTransColor,
  407. llElapsedTicks, ulCallDepth);
  408. if(bSurfaceChecks)
  409. vCheckSurfaceChecksums(psoDst, psoSrc);
  410. ulCallDepth--;
  411. return bResult;
  412. }
  413. //------------------------------------------------------------------------------
  414. //
  415. // BOOL xDrvAlphaBlend
  416. //
  417. // Thunk layer wrapper for DrvAlphaBlend.
  418. //
  419. //------------------------------------------------------------------------------
  420. BOOL
  421. xDrvAlphaBlend(
  422. SURFOBJ *psoDst,
  423. SURFOBJ *psoSrc,
  424. CLIPOBJ *pco,
  425. XLATEOBJ *pxlo,
  426. RECTL *prclDst,
  427. RECTL *prclSrc,
  428. BLENDOBJ *pBlendObj)
  429. {
  430. BOOL bResult;
  431. LONGLONG llStartTicks;
  432. LONGLONG llElapsedTicks;
  433. ulCallDepth++;
  434. if(bSurfaceChecks)
  435. vCalcSurfaceChecksums(psoDst, psoSrc);
  436. EngQueryPerformanceCounter(&llStartTicks);
  437. bResult = DrvAlphaBlend(
  438. psoDst, psoSrc, pco, pxlo, prclDst, prclSrc, pBlendObj);
  439. EngQueryPerformanceCounter(&llElapsedTicks);
  440. llElapsedTicks -= llStartTicks;
  441. vLogAlphaBlend(psoDst, psoSrc, pco, pxlo, prclDst, prclSrc, pBlendObj,
  442. llElapsedTicks, ulCallDepth);
  443. if(bSurfaceChecks)
  444. vCheckSurfaceChecksums(psoDst, psoSrc);
  445. ulCallDepth--;
  446. return bResult;
  447. }
  448. //------------------------------------------------------------------------------
  449. //
  450. // BOOL xDrvGradientFill
  451. //
  452. // Thunk layer wrapper for DrvGradientFill.
  453. //
  454. //------------------------------------------------------------------------------
  455. BOOL
  456. xDrvGradientFill(
  457. SURFOBJ *psoDst,
  458. CLIPOBJ *pco,
  459. XLATEOBJ *pxlo,
  460. TRIVERTEX *pVertex,
  461. ULONG nVertex,
  462. PVOID pMesh,
  463. ULONG nMesh,
  464. RECTL *prclExtents,
  465. POINTL *pptlDitherOrg,
  466. ULONG ulMode
  467. )
  468. {
  469. BOOL bResult;
  470. LONGLONG llStartTicks;
  471. LONGLONG llElapsedTicks;
  472. ulCallDepth++;
  473. if(bSurfaceChecks)
  474. vCalcSurfaceChecksums(psoDst, NULL);
  475. EngQueryPerformanceCounter(&llStartTicks);
  476. bResult = DrvGradientFill(
  477. psoDst, pco, pxlo, pVertex, nVertex,
  478. pMesh, nMesh, prclExtents, pptlDitherOrg, ulMode);
  479. EngQueryPerformanceCounter(&llElapsedTicks);
  480. llElapsedTicks -= llStartTicks;
  481. vLogGradientFill(psoDst, pco, pxlo, pVertex, nVertex, pMesh, nMesh,
  482. prclExtents, pptlDitherOrg, ulMode,
  483. llElapsedTicks, ulCallDepth);
  484. if(bSurfaceChecks)
  485. vCheckSurfaceChecksums(psoDst, NULL);
  486. ulCallDepth--;
  487. return bResult;
  488. }
  489. //------------------------------------------------------------------------------
  490. //
  491. // BOOL xDrvTextOut
  492. //
  493. // Thunk layer wrapper for DrvTextOut.
  494. //
  495. //------------------------------------------------------------------------------
  496. BOOL
  497. xDrvTextOut(SURFOBJ* pso,
  498. STROBJ* pstro,
  499. FONTOBJ* pfo,
  500. CLIPOBJ* pco,
  501. RECTL* prclExtra,
  502. RECTL* prclOpaque,
  503. BRUSHOBJ* pboFore,
  504. BRUSHOBJ* pboOpaque,
  505. POINTL* pptlBrush,
  506. MIX mix)
  507. {
  508. BOOL bResult;
  509. LONGLONG llStartTicks;
  510. LONGLONG llElapsedTicks;
  511. ulCallDepth++;
  512. if(bSurfaceChecks)
  513. vCalcSurfaceChecksums(pso, NULL);
  514. EngQueryPerformanceCounter(&llStartTicks);
  515. bResult = DrvTextOut(pso, pstro, pfo, pco, prclExtra, prclOpaque,
  516. pboFore, pboOpaque, pptlBrush, mix);
  517. EngQueryPerformanceCounter(&llElapsedTicks);
  518. llElapsedTicks -= llStartTicks;
  519. vLogTextOut(pso, pstro, pfo, pco, prclExtra, prclOpaque,
  520. pboFore, pboOpaque, pptlBrush, mix,
  521. llElapsedTicks, ulCallDepth);
  522. if(bSurfaceChecks)
  523. vCheckSurfaceChecksums(pso, NULL);
  524. ulCallDepth--;
  525. return bResult;
  526. }
  527. //------------------------------------------------------------------------------
  528. //
  529. // BOOL xDrvLineTo
  530. //
  531. // Thunk layer wrapper for DrvLineTo.
  532. //
  533. //------------------------------------------------------------------------------
  534. BOOL
  535. xDrvLineTo(
  536. SURFOBJ* pso,
  537. CLIPOBJ* pco,
  538. BRUSHOBJ* pbo,
  539. LONG x1,
  540. LONG y1,
  541. LONG x2,
  542. LONG y2,
  543. RECTL* prclBounds,
  544. MIX mix)
  545. {
  546. BOOL bResult;
  547. LONGLONG llStartTicks;
  548. LONGLONG llElapsedTicks;
  549. ulCallDepth++;
  550. if(bSurfaceChecks)
  551. vCalcSurfaceChecksums(pso, NULL);
  552. EngQueryPerformanceCounter(&llStartTicks);
  553. bResult = DrvLineTo(pso, pco, pbo, x1, y1, x2, y2, prclBounds, mix);
  554. EngQueryPerformanceCounter(&llElapsedTicks);
  555. llElapsedTicks -= llStartTicks;
  556. vLogLineTo(pso, pco, pbo, x1, y1, x2, y2, prclBounds, mix,
  557. llElapsedTicks, ulCallDepth);
  558. if(bSurfaceChecks)
  559. vCheckSurfaceChecksums(pso, NULL);
  560. ulCallDepth--;
  561. return bResult;
  562. }
  563. //------------------------------------------------------------------------------
  564. //
  565. // BOOL xDrvFillPath
  566. //
  567. // Thunk layer wrapper for DrvFillPath.
  568. //
  569. //------------------------------------------------------------------------------
  570. BOOL
  571. xDrvFillPath(
  572. SURFOBJ* pso,
  573. PATHOBJ* ppo,
  574. CLIPOBJ* pco,
  575. BRUSHOBJ* pbo,
  576. POINTL* pptlBrush,
  577. MIX mix,
  578. FLONG flOptions)
  579. {
  580. BOOL bResult;
  581. LONGLONG llStartTicks;
  582. LONGLONG llElapsedTicks;
  583. ulCallDepth++;
  584. if(bSurfaceChecks)
  585. vCalcSurfaceChecksums(pso, NULL);
  586. EngQueryPerformanceCounter(&llStartTicks);
  587. bResult = DrvFillPath(pso, ppo, pco, pbo, pptlBrush, mix, flOptions);
  588. EngQueryPerformanceCounter(&llElapsedTicks);
  589. llElapsedTicks -= llStartTicks;
  590. vLogFillPath(pso, ppo, pco, pbo, pptlBrush, mix, flOptions,
  591. llElapsedTicks, ulCallDepth);
  592. if(bSurfaceChecks)
  593. vCheckSurfaceChecksums(pso, NULL);
  594. ulCallDepth--;
  595. return bResult;
  596. }
  597. //------------------------------------------------------------------------------
  598. //
  599. // BOOL xDrvStrokePath
  600. //
  601. // Thunk layer wrapper for DrvStrokePath.
  602. //
  603. //------------------------------------------------------------------------------
  604. BOOL
  605. xDrvStrokePath(
  606. SURFOBJ* pso,
  607. PATHOBJ* ppo,
  608. CLIPOBJ* pco,
  609. XFORMOBJ* pxo,
  610. BRUSHOBJ* pbo,
  611. POINTL* pptlBrush,
  612. LINEATTRS* pla,
  613. MIX mix)
  614. {
  615. BOOL bResult;
  616. LONGLONG llStartTicks;
  617. LONGLONG llElapsedTicks;
  618. ulCallDepth++;
  619. if(bSurfaceChecks)
  620. vCalcSurfaceChecksums(pso, NULL);
  621. EngQueryPerformanceCounter(&llStartTicks);
  622. bResult = DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrush, pla, mix);
  623. EngQueryPerformanceCounter(&llElapsedTicks);
  624. llElapsedTicks -= llStartTicks;
  625. vLogStrokePath(pso, ppo, pco, pxo, pbo, pptlBrush, pla, mix,
  626. llElapsedTicks, ulCallDepth);
  627. if(bSurfaceChecks)
  628. vCheckSurfaceChecksums(pso, NULL);
  629. ulCallDepth--;
  630. return bResult;
  631. }
  632. #endif // THUNK LAYER
  633. //-----------------------------------------------------------------------------
  634. //
  635. //..Add some functions to aid tracking down memory leaks.
  636. // Its sole purpose is tracking down leaks, so its not optimized for speed.
  637. // WARNING: If two instances of same driver are active at the same time,
  638. // it will track the memory allocations of both.
  639. //
  640. // To keep it simple, we just allocate an array here where we store memory allocations.
  641. // There is some simple algorithm to keep track of recently freed entries. Anyway,
  642. // to free a piece of memory we have to search through the whole table. So better
  643. // use for debugging memory holes.
  644. //
  645. //-----------------------------------------------------------------------------
  646. #if DBG && TRACKMEMALLOC
  647. typedef struct tagMemTrackInfo {
  648. PVOID pMemory;
  649. LONG lSize;
  650. PCHAR pModule;
  651. LONG lLineNo;
  652. //LONGINT save time of allocation?
  653. BOOL bStopWhenFreed;
  654. BOOL bTemp;
  655. } MemTrackInfo, *PMemTrackInfo;
  656. #define NEWCHUNKSIZE 256
  657. static PMemTrackInfo pTrackPool=NULL;
  658. static LONG lTrackPoolTotalSize=0;
  659. static LONG lTrackPoolSize=0;
  660. static LONG lInstances=0;
  661. static LONG lTotalAllocatedMemory=0;
  662. static LONG lNextFreeEntry=0;
  663. // glMemTrackerVerboseMode--- set flags according to debug output
  664. // 0 no output
  665. // 1 print summary for all allocations in same module/LineNo
  666. // 2 print all entries
  667. LONG glMemTrackerVerboseMode=1;
  668. //-----------------------------------------------------------------------------
  669. //
  670. // MemTrackerAddInstance
  671. //
  672. // Just count number of active instances of the driver
  673. //
  674. //-----------------------------------------------------------------------------
  675. VOID MemTrackerAddInstance()
  676. {
  677. lInstances++;
  678. }
  679. //-----------------------------------------------------------------------------
  680. //
  681. // MemTrackerRemInstance
  682. //
  683. // Just count number of active instances of the driver. Free Tracker memory
  684. // if last instance is destroyed!!!
  685. //
  686. //-----------------------------------------------------------------------------
  687. VOID MemTrackerRemInstance()
  688. {
  689. lInstances--;
  690. if (lInstances==0)
  691. {
  692. EngFreeMem(pTrackPool);
  693. pTrackPool=NULL;
  694. lTrackPoolTotalSize=0;
  695. lTrackPoolSize=0;
  696. lTotalAllocatedMemory=0;
  697. lNextFreeEntry=0;
  698. }
  699. }
  700. //-----------------------------------------------------------------------------
  701. //
  702. // MemTrackerAllocateMem
  703. //
  704. // Add memory top be tracked to table.
  705. //
  706. // p--------address of memory chunk
  707. // lSize----Size of memory chunk
  708. // pModulo--module name
  709. // lLineNo--module line number
  710. // bStopWhenFreed--set a breakpoint if this memory is freed (not yet used)
  711. //
  712. //-----------------------------------------------------------------------------
  713. PVOID MemTrackerAllocateMem(PVOID p,
  714. LONG lSize,
  715. PCHAR pModule,
  716. LONG lLineNo,
  717. BOOL bStopWhenFreed)
  718. {
  719. // check for first time allocation
  720. if (p==NULL) return p;
  721. if (pTrackPool==NULL)
  722. {
  723. pTrackPool=(PMemTrackInfo)EngAllocMem( FL_ZERO_MEMORY,
  724. NEWCHUNKSIZE*sizeof(MemTrackInfo),
  725. ALLOC_TAG);
  726. if (pTrackPool==NULL) return p;
  727. lTrackPoolTotalSize=NEWCHUNKSIZE;
  728. lTrackPoolSize=2;
  729. lTotalAllocatedMemory=0;
  730. lNextFreeEntry=1;
  731. pTrackPool[0].pMemory= pTrackPool;
  732. pTrackPool[0].lSize= NEWCHUNKSIZE*sizeof(MemTrackInfo);
  733. pTrackPool[0].pModule= __FILE__;
  734. pTrackPool[0].lLineNo= __LINE__;
  735. pTrackPool[0].bStopWhenFreed=FALSE;
  736. }
  737. if (lTrackPoolSize>=lTrackPoolTotalSize)
  738. { // reallocation necessary
  739. LONG lNewTrackPoolTotalSize=lTrackPoolTotalSize+NEWCHUNKSIZE;
  740. LONG lNewSize;
  741. PMemTrackInfo pNewTrackPool=(PMemTrackInfo)
  742. EngAllocMem( FL_ZERO_MEMORY, lNewSize=lNewTrackPoolTotalSize*sizeof(MemTrackInfo), ALLOC_TAG);
  743. if (pNewTrackPool==NULL) return p;
  744. memcpy( pNewTrackPool, pTrackPool, lTrackPoolTotalSize*sizeof(MemTrackInfo));
  745. EngFreeMem( pTrackPool);
  746. pTrackPool=pNewTrackPool;
  747. lTrackPoolTotalSize=lNewTrackPoolTotalSize;
  748. pTrackPool[0].pMemory= pTrackPool;
  749. pTrackPool[0].lSize= lNewSize;
  750. pTrackPool[0].pModule= __FILE__;
  751. pTrackPool[0].lLineNo= __LINE__;
  752. pTrackPool[0].bStopWhenFreed=FALSE;
  753. }
  754. LONG lThisEntry=lNextFreeEntry;
  755. lNextFreeEntry=pTrackPool[lThisEntry].lSize;
  756. pTrackPool[lThisEntry].pMemory= p;
  757. pTrackPool[lThisEntry].lSize= lSize;
  758. pTrackPool[lThisEntry].pModule= pModule;
  759. pTrackPool[lThisEntry].lLineNo= lLineNo;
  760. pTrackPool[lThisEntry].bStopWhenFreed=FALSE;
  761. if (lNextFreeEntry==0)
  762. {
  763. lNextFreeEntry=lTrackPoolSize;
  764. lTrackPoolSize++;
  765. }
  766. lTotalAllocatedMemory += lSize;
  767. return p;
  768. }
  769. //-----------------------------------------------------------------------------
  770. //
  771. // MemTrackerFreeMem
  772. //
  773. // remove a memory chunk from table, because it is freed
  774. //
  775. // p-----address of memory to be removed from table
  776. //
  777. //-----------------------------------------------------------------------------
  778. VOID MemTrackerFreeMem( VOID *p)
  779. {
  780. for (INT i=1; i<lTrackPoolSize; i++)
  781. {
  782. if (pTrackPool[i].pMemory==p)
  783. {
  784. lTotalAllocatedMemory -= pTrackPool[i].lSize;
  785. pTrackPool[i].pMemory=NULL;
  786. pTrackPool[i].lSize=lNextFreeEntry;
  787. pTrackPool[i].pModule=NULL;
  788. pTrackPool[i].lLineNo=0;
  789. pTrackPool[i].bStopWhenFreed=FALSE;
  790. lNextFreeEntry = i;
  791. return;
  792. }
  793. }
  794. DISPDBG(( 0, "freeing some piece of memory which was not allocated in this context"));
  795. }
  796. //-----------------------------------------------------------------------------
  797. //
  798. // MemTrackerDebugChk
  799. //
  800. // print out some debug info about tracked memory
  801. //
  802. //-----------------------------------------------------------------------------
  803. VOID MemTrackerDebugChk()
  804. {
  805. if (glMemTrackerVerboseMode==0) return;
  806. DISPDBG(( 0, "MemTracker: %ld total allocated memory (%ld for tracker, total %ld)",
  807. lTotalAllocatedMemory, pTrackPool[0].lSize,pTrackPool[0].lSize+lTotalAllocatedMemory));
  808. LONG lTotalTrackedMemory=0;
  809. for (INT i=0; i<lTrackPoolSize; i++)
  810. {
  811. pTrackPool[i].bTemp=FALSE;
  812. if (pTrackPool[i].pMemory!=NULL)
  813. {
  814. lTotalTrackedMemory += pTrackPool[i].lSize;
  815. if (glMemTrackerVerboseMode & 2)
  816. {
  817. DISPDBG((0, "%5ld:%s, line %5ld: %ld b, %p",
  818. i,
  819. pTrackPool[i].lLineNo,
  820. pTrackPool[i].pModule,
  821. pTrackPool[i].lSize,
  822. pTrackPool[i].pMemory));
  823. }
  824. }
  825. }
  826. DISPDBG(( 0, " sanity check: %ld bytes allocated", lTotalTrackedMemory));
  827. if (!(glMemTrackerVerboseMode & 1))
  828. return;
  829. for (i=1; i<lTrackPoolSize; i++)
  830. {
  831. if ( pTrackPool[i].pMemory!=NULL &&
  832. !pTrackPool[i].bTemp)
  833. {
  834. LONG lAllocations=0;
  835. LONG lTrackedMemory=0;
  836. for (INT v=i; v<lTrackPoolSize; v++)
  837. {
  838. if (!pTrackPool[v].bTemp &&
  839. pTrackPool[v].lLineNo==pTrackPool[i].lLineNo &&
  840. pTrackPool[v].pModule==pTrackPool[i].pModule)
  841. {
  842. pTrackPool[v].bTemp=TRUE;
  843. lAllocations++;
  844. lTrackedMemory+=pTrackPool[v].lSize;
  845. }
  846. }
  847. DISPDBG((0, " %s, line %5ld: %ld bytes total, %ld allocations",
  848. pTrackPool[i].pModule,
  849. pTrackPool[i].lLineNo,
  850. lTrackedMemory,
  851. lAllocations
  852. ));
  853. }
  854. }
  855. }
  856. #endif
  857. ////////////////////////////////////////////////////////////////////////////
  858. static DWORD readableRegistersP2[] = {
  859. __Permedia2TagStartXDom,
  860. __Permedia2TagdXDom,
  861. __Permedia2TagStartXSub,
  862. __Permedia2TagdXSub,
  863. __Permedia2TagStartY,
  864. __Permedia2TagdY,
  865. __Permedia2TagCount,
  866. __Permedia2TagRasterizerMode,
  867. __Permedia2TagYLimits,
  868. __Permedia2TagXLimits,
  869. __Permedia2TagScissorMode,
  870. __Permedia2TagScissorMinXY,
  871. __Permedia2TagScissorMaxXY,
  872. __Permedia2TagScreenSize,
  873. __Permedia2TagAreaStippleMode,
  874. __Permedia2TagWindowOrigin,
  875. __Permedia2TagAreaStipplePattern0,
  876. __Permedia2TagAreaStipplePattern1,
  877. __Permedia2TagAreaStipplePattern2,
  878. __Permedia2TagAreaStipplePattern3,
  879. __Permedia2TagAreaStipplePattern4,
  880. __Permedia2TagAreaStipplePattern5,
  881. __Permedia2TagAreaStipplePattern6,
  882. __Permedia2TagAreaStipplePattern7,
  883. __Permedia2TagTextureAddressMode,
  884. __Permedia2TagSStart,
  885. __Permedia2TagdSdx,
  886. __Permedia2TagdSdyDom,
  887. __Permedia2TagTStart,
  888. __Permedia2TagdTdx,
  889. __Permedia2TagdTdyDom,
  890. __Permedia2TagQStart,
  891. __Permedia2TagdQdx,
  892. __Permedia2TagdQdyDom,
  893. // texellutindex..transfer are treated seperately
  894. __Permedia2TagTextureBaseAddress,
  895. __Permedia2TagTextureMapFormat,
  896. __Permedia2TagTextureDataFormat,
  897. __Permedia2TagTexel0,
  898. __Permedia2TagTextureReadMode,
  899. __Permedia2TagTexelLUTMode,
  900. __Permedia2TagTextureColorMode,
  901. __Permedia2TagFogMode,
  902. __Permedia2TagFogColor,
  903. __Permedia2TagFStart,
  904. __Permedia2TagdFdx,
  905. __Permedia2TagdFdyDom,
  906. __Permedia2TagKsStart,
  907. __Permedia2TagdKsdx,
  908. __Permedia2TagdKsdyDom,
  909. __Permedia2TagKdStart,
  910. __Permedia2TagdKddx,
  911. __Permedia2TagdKddyDom,
  912. __Permedia2TagRStart,
  913. __Permedia2TagdRdx,
  914. __Permedia2TagdRdyDom,
  915. __Permedia2TagGStart,
  916. __Permedia2TagdGdx,
  917. __Permedia2TagdGdyDom,
  918. __Permedia2TagBStart,
  919. __Permedia2TagdBdx,
  920. __Permedia2TagdBdyDom,
  921. __Permedia2TagAStart,
  922. __Permedia2TagColorDDAMode,
  923. __Permedia2TagConstantColor,
  924. __Permedia2TagAlphaBlendMode,
  925. __Permedia2TagDitherMode,
  926. __Permedia2TagFBSoftwareWriteMask,
  927. __Permedia2TagLogicalOpMode,
  928. __Permedia2TagLBReadMode,
  929. __Permedia2TagLBReadFormat,
  930. __Permedia2TagLBSourceOffset,
  931. __Permedia2TagLBWindowBase,
  932. __Permedia2TagLBWriteMode,
  933. __Permedia2TagLBWriteFormat,
  934. __Permedia2TagTextureDownloadOffset,
  935. __Permedia2TagWindow,
  936. __Permedia2TagStencilMode,
  937. __Permedia2TagStencilData,
  938. __Permedia2TagStencil,
  939. __Permedia2TagDepthMode,
  940. __Permedia2TagDepth,
  941. __Permedia2TagZStartU,
  942. __Permedia2TagZStartL,
  943. __Permedia2TagdZdxU,
  944. __Permedia2TagdZdxL,
  945. __Permedia2TagdZdyDomU,
  946. __Permedia2TagdZdyDomL,
  947. __Permedia2TagFBReadMode,
  948. __Permedia2TagFBSourceOffset,
  949. __Permedia2TagFBPixelOffset,
  950. __Permedia2TagFBWindowBase,
  951. __Permedia2TagFBWriteMode,
  952. __Permedia2TagFBHardwareWriteMask,
  953. __Permedia2TagFBBlockColor,
  954. __Permedia2TagFBReadPixel,
  955. __Permedia2TagFilterMode,
  956. __Permedia2TagStatisticMode,
  957. __Permedia2TagMinRegion,
  958. __Permedia2TagMaxRegion,
  959. __Permedia2TagFBBlockColorU,
  960. __Permedia2TagFBBlockColorL,
  961. __Permedia2TagFBSourceBase,
  962. __Permedia2TagTexelLUT0,
  963. __Permedia2TagTexelLUT1,
  964. __Permedia2TagTexelLUT2,
  965. __Permedia2TagTexelLUT3,
  966. __Permedia2TagTexelLUT4,
  967. __Permedia2TagTexelLUT5,
  968. __Permedia2TagTexelLUT6,
  969. __Permedia2TagTexelLUT7,
  970. __Permedia2TagTexelLUT8,
  971. __Permedia2TagTexelLUT9,
  972. __Permedia2TagTexelLUT10,
  973. __Permedia2TagTexelLUT11,
  974. __Permedia2TagTexelLUT12,
  975. __Permedia2TagTexelLUT13,
  976. __Permedia2TagTexelLUT14,
  977. __Permedia2TagTexelLUT15,
  978. __Permedia2TagYUVMode,
  979. __Permedia2TagChromaUpperBound,
  980. __Permedia2TagChromaLowerBound,
  981. __Permedia2TagAlphaMapUpperBound,
  982. __Permedia2TagAlphaMapLowerBound,
  983. // delta tag values. must be at the end of this array
  984. // v0/1/2 fixed are not used and for that reason not in the context
  985. __Permedia2TagV0FloatS,
  986. __Permedia2TagV0FloatT,
  987. __Permedia2TagV0FloatQ,
  988. __Permedia2TagV0FloatKs,
  989. __Permedia2TagV0FloatKd,
  990. __Permedia2TagV0FloatR,
  991. __Permedia2TagV0FloatG,
  992. __Permedia2TagV0FloatB,
  993. __Permedia2TagV0FloatA,
  994. __Permedia2TagV0FloatF,
  995. __Permedia2TagV0FloatX,
  996. __Permedia2TagV0FloatY,
  997. __Permedia2TagV0FloatZ,
  998. __Permedia2TagV1FloatS,
  999. __Permedia2TagV1FloatT,
  1000. __Permedia2TagV1FloatQ,
  1001. __Permedia2TagV1FloatKs,
  1002. __Permedia2TagV1FloatKd,
  1003. __Permedia2TagV1FloatR,
  1004. __Permedia2TagV1FloatG,
  1005. __Permedia2TagV1FloatB,
  1006. __Permedia2TagV1FloatA,
  1007. __Permedia2TagV1FloatF,
  1008. __Permedia2TagV1FloatX,
  1009. __Permedia2TagV1FloatY,
  1010. __Permedia2TagV1FloatZ,
  1011. __Permedia2TagV2FloatS,
  1012. __Permedia2TagV2FloatT,
  1013. __Permedia2TagV2FloatQ,
  1014. __Permedia2TagV2FloatKs,
  1015. __Permedia2TagV2FloatKd,
  1016. __Permedia2TagV2FloatR,
  1017. __Permedia2TagV2FloatG,
  1018. __Permedia2TagV2FloatB,
  1019. __Permedia2TagV2FloatA,
  1020. __Permedia2TagV2FloatF,
  1021. __Permedia2TagV2FloatX,
  1022. __Permedia2TagV2FloatY,
  1023. __Permedia2TagV2FloatZ,
  1024. __Permedia2TagDeltaMode};
  1025. #define N_P2_READABLE_REGISTERS (sizeof(readableRegistersP2)/sizeof(DWORD))
  1026. static DWORD P2SaveRegs[N_P2_READABLE_REGISTERS];
  1027. static PCHAR szReadableRegistersP2[] = {
  1028. "StartXDom",
  1029. "dXDom",
  1030. "StartXSub",
  1031. "dXSub",
  1032. "StartY",
  1033. "dY",
  1034. "Count",
  1035. "RasterizerMode",
  1036. "YLimits",
  1037. "XLimits",
  1038. "ScissorMode",
  1039. "ScissorMinXY",
  1040. "ScissorMaxXY",
  1041. "ScreenSize",
  1042. "AreaStippleMode",
  1043. "WindowOrigin",
  1044. "AreaStipplePattern0",
  1045. "AreaStipplePattern1",
  1046. "AreaStipplePattern2",
  1047. "AreaStipplePattern3",
  1048. "AreaStipplePattern4",
  1049. "AreaStipplePattern5",
  1050. "AreaStipplePattern6",
  1051. "AreaStipplePattern7",
  1052. "TextureAddressMode",
  1053. "SStart",
  1054. "dSdx",
  1055. "dSdyDom",
  1056. "TStart",
  1057. "dTdx",
  1058. "dTdyDom",
  1059. "QStart",
  1060. "dQdx",
  1061. "dQdyDom",
  1062. "TextureBaseAddress",
  1063. "TextureMapFormat",
  1064. "TextureDataFormat",
  1065. "Texel0",
  1066. "TextureReadMode",
  1067. "TexelLUTMode",
  1068. "TextureColorMode",
  1069. "FogMode",
  1070. "FogColor",
  1071. "FStart",
  1072. "dFdx",
  1073. "dFdyDom",
  1074. "KsStart",
  1075. "dKsdx",
  1076. "dKsdyDom",
  1077. "KdStart",
  1078. "dKddx",
  1079. "dKddyDom",
  1080. "RStart",
  1081. "dRdx",
  1082. "dRdyDom",
  1083. "GStart",
  1084. "dGdx",
  1085. "dGdyDom",
  1086. "BStart",
  1087. "dBdx",
  1088. "dBdyDom",
  1089. "AStart",
  1090. "ColorDDAMode",
  1091. "ConstantColor",
  1092. "AlphaBlendMode",
  1093. "DitherMode",
  1094. "FBSoftwareWriteMask",
  1095. "LogicalOpMode",
  1096. "LBReadMode",
  1097. "LBReadFormat",
  1098. "LBSourceOffset",
  1099. "LBWindowBase",
  1100. "LBWriteMode",
  1101. "LBWriteFormat",
  1102. "TextureDownloadOffset",
  1103. "Window",
  1104. "StencilMode",
  1105. "StencilData",
  1106. "Stencil",
  1107. "DepthMode",
  1108. "Depth",
  1109. "ZStartU",
  1110. "ZStartL",
  1111. "dZdxU",
  1112. "dZdxL",
  1113. "dZdyDomU",
  1114. "dZdyDomL",
  1115. "FBReadMode",
  1116. "FBSourceOffset",
  1117. "FBPixelOffset",
  1118. "FBWindowBase",
  1119. "FBWriteMode",
  1120. "FBHardwareWriteMask",
  1121. "FBBlockColor",
  1122. "FBReadPixel",
  1123. "FilterMode",
  1124. "StatisticMode",
  1125. "MinRegion",
  1126. "MaxRegion",
  1127. "FBBlockColorU",
  1128. "FBBlockColorL",
  1129. "FBSourceBase",
  1130. "TexelLUT0",
  1131. "TexelLUT1",
  1132. "TexelLUT2",
  1133. "TexelLUT3",
  1134. "TexelLUT4",
  1135. "TexelLUT5",
  1136. "TexelLUT6",
  1137. "TexelLUT7",
  1138. "TexelLUT8",
  1139. "TexelLUT9",
  1140. "TexelLUT10",
  1141. "TexelLUT11",
  1142. "TexelLUT12",
  1143. "TexelLUT13",
  1144. "TexelLUT14",
  1145. "TexelLUT15",
  1146. "YUVMode",
  1147. "ChromaUpperBound",
  1148. "ChromaLowerBound",
  1149. "AlphaMapUpperBound",
  1150. "AlphaMapLowerBound",
  1151. // delta tag values. must be at the end of this array
  1152. // v0/1/2 fixed are not used and for that reason not in the context
  1153. "V0FloatS",
  1154. "V0FloatT",
  1155. "V0FloatQ",
  1156. "V0FloatKs",
  1157. "V0FloatKd",
  1158. "V0FloatR",
  1159. "V0FloatG",
  1160. "V0FloatB",
  1161. "V0FloatA",
  1162. "V0FloatF",
  1163. "V0FloatX",
  1164. "V0FloatY",
  1165. "V0FloatZ",
  1166. "V1FloatS",
  1167. "V1FloatT",
  1168. "V1FloatQ",
  1169. "V1FloatKs",
  1170. "V1FloatKd",
  1171. "V1FloatR",
  1172. "V1FloatG",
  1173. "V1FloatB",
  1174. "V1FloatA",
  1175. "V1FloatF",
  1176. "V1FloatX",
  1177. "V1FloatY",
  1178. "V1FloatZ",
  1179. "V2FloatS",
  1180. "V2FloatT",
  1181. "V2FloatQ",
  1182. "V2FloatKs",
  1183. "V2FloatKd",
  1184. "V2FloatR",
  1185. "V2FloatG",
  1186. "V2FloatB",
  1187. "V2FloatA",
  1188. "V2FloatF",
  1189. "V2FloatX",
  1190. "V2FloatY",
  1191. "V2FloatZ",
  1192. "DeltaMode"
  1193. };
  1194. VOID PrintAllP2Registers( ULONG ulDebugLevel, PPDev ppdev)
  1195. {
  1196. PERMEDIA_DEFS(ppdev);
  1197. INT i;
  1198. SYNC_WITH_PERMEDIA;
  1199. DISPDBG((ulDebugLevel,"dumping P2 register set"));
  1200. for (i=0;i<N_P2_READABLE_REGISTERS;i++)
  1201. {
  1202. DWORD lValue=READ_FIFO_REG(readableRegistersP2[i]);
  1203. DISPDBG((ulDebugLevel," %-25s, 0x%08lx",szReadableRegistersP2[i],lValue));
  1204. }
  1205. }
  1206. VOID SaveAllP2Registers( PPDev ppdev)
  1207. {
  1208. PERMEDIA_DEFS(ppdev);
  1209. INT i;
  1210. SYNC_WITH_PERMEDIA;
  1211. for (i=0;i<N_P2_READABLE_REGISTERS;i++)
  1212. {
  1213. P2SaveRegs[i]=READ_FIFO_REG(readableRegistersP2[i]);
  1214. }
  1215. }
  1216. VOID PrintDifferentP2Registers(ULONG ulDebugLevel, PPDev ppdev)
  1217. {
  1218. PERMEDIA_DEFS(ppdev);
  1219. INT i;
  1220. SYNC_WITH_PERMEDIA;
  1221. DISPDBG((ulDebugLevel,"dumping P2 register set"));
  1222. for (i=0;i<N_P2_READABLE_REGISTERS;i++)
  1223. {
  1224. DWORD dwValue=READ_FIFO_REG(readableRegistersP2[i]);
  1225. if (P2SaveRegs[i]!=dwValue)
  1226. {
  1227. DISPDBG((ulDebugLevel," %-25s, 0x%08lx was 0x%08lx",
  1228. szReadableRegistersP2[i], dwValue, P2SaveRegs[i]));
  1229. }
  1230. }
  1231. }
  1232. #endif // DBG