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.

674 lines
18 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: DEV2DEV.c
  3. *
  4. * Author: Noel VanHook
  5. *
  6. * Purpose: Handle device to device BLTs.
  7. *
  8. * Copyright (c) 1997 Cirrus Logic, Inc.
  9. *
  10. * $Log: X:/log/laguna/nt35/displays/cl546x/dev2dev.c $
  11. *
  12. * Rev 1.11 Mar 04 1998 15:13:52 frido
  13. * Added new shadow macros.
  14. *
  15. * Rev 1.10 Jan 22 1998 16:20:10 frido
  16. * Added 16-bit striping code.
  17. *
  18. * Rev 1.9 Jan 21 1998 13:46:52 frido
  19. * Fixed the striping code since this is really the first time we check it.
  20. *
  21. * Rev 1.8 Jan 20 1998 11:43:26 frido
  22. * Guess what? Striping was not turned on!
  23. *
  24. * Rev 1.7 Dec 10 1997 13:32:12 frido
  25. * Merged from 1.62 branch.
  26. *
  27. * Rev 1.6.1.2 Dec 05 1997 13:34:26 frido
  28. * PDR#11043. When using a brush, striping should use pixels instead of
  29. * bytes, so now there is an intelligent switcher in place.
  30. *
  31. * Rev 1.6.1.1 Nov 18 1997 15:14:56 frido
  32. * Added striping for 24-bpp.
  33. *
  34. * Rev 1.6.1.0 Nov 10 1997 13:39:26 frido
  35. * PDR#10893: Inside DoDeviceToDeviceWithXlate the source pointer
  36. * was not updated after each access.
  37. *
  38. * Rev 1.6 Nov 04 1997 13:40:56 frido
  39. * I removed a little too much code in DoDeviceToDevice. The result was
  40. * a very slow screen-to-screen blits since everything was punted back to
  41. * GDI.
  42. *
  43. * Rev 1.5 Nov 04 1997 09:49:18 frido
  44. * Added COLOR_TRANSLATE switches around hardware color translation code.
  45. *
  46. * Rev 1.4 Nov 03 1997 15:20:06 frido
  47. * Added REQUIRE macros.
  48. *
  49. * Rev 1.3 15 Oct 1997 12:03:00 noelv
  50. * Pass rop code to CacheXlateTable().
  51. *
  52. * Rev 1.2 02 Oct 1997 09:48:22 noelv
  53. *
  54. * Hardwre color translation only works with CC rop code.
  55. *
  56. * Rev 1.1 19 Feb 1997 13:14:22 noelv
  57. *
  58. * Fixed LL_BLTEXT_XLATE()
  59. *
  60. * Rev 1.0 06 Feb 1997 10:35:48 noelv
  61. * Initial revision.
  62. *
  63. \**************************************************************************/
  64. #include "precomp.h"
  65. #define DEV2DEV_DBG_LEVEL 0
  66. //
  67. // Set to 1 to stripe screen to screen operations along tile boundries.
  68. // Set to 0 to do screen to screen operations in a few BLTs as possible.
  69. //
  70. // on the 62, 64 and 65 striping is faster than not striping.
  71. //
  72. #define STRIPE_SCR2SCR 1
  73. //
  74. // internal prototypes.
  75. //
  76. BOOL DoDeviceToDeviceWithXlate(
  77. SURFOBJ *psoTrg,
  78. SURFOBJ *psoSrc,
  79. ULONG *pulXlate,
  80. RECTL *prclTrg,
  81. POINTL *pptlSrc,
  82. ULONG ulDRAWBLTDEF
  83. );
  84. /*****************************************************************************\
  85. * DoDeviceToDevice
  86. *
  87. * This routine performs a ScreenToScreen, DeviceToScreen or ScreenToDevice
  88. * blit. If there is a color translation table, we will attempt to use
  89. * the hardware color translator. If we can't (or don't have one) we will
  90. * pass the call to DoDeviceToDeviceWithXlate, which will do the color
  91. * translation is software.
  92. *
  93. * On entry: psoTrg Pointer to target surface object.
  94. * psoSrc Pointer to source surface object.
  95. * pxlo Pointer to translation object.
  96. * prclTrg Destination rectangle.
  97. * pptlSrc Source offset.
  98. * ulDRAWBLTDEF Value for grDRAWBLTDEF register. This value has
  99. * The ROP and the brush flags.
  100. \*****************************************************************************/
  101. BOOL DoDeviceToDevice(
  102. SURFOBJ *psoTrg,
  103. SURFOBJ *psoSrc,
  104. XLATEOBJ *pxlo,
  105. RECTL *prclTrg,
  106. POINTL *pptlSrc,
  107. ULONG ulDRAWBLTDEF
  108. )
  109. {
  110. POINTL ptlSrc, ptlDest;
  111. SIZEL sizl;
  112. PPDEV ppdev;
  113. LONG tileSize, maxStripeWidth;
  114. ULONG* pulXlate;
  115. BOOL fStripePixels;
  116. BOOL fFirst = TRUE;
  117. //
  118. // Determine the source type and adjust the source offset.
  119. //
  120. if (psoSrc->iType == STYPE_DEVBITMAP)
  121. {
  122. // Source is a device bitmap.
  123. PDSURF pdsurf = (PDSURF) psoSrc->dhsurf;
  124. ptlSrc.x = pptlSrc->x + pdsurf->ptl.x;
  125. ptlSrc.y = pptlSrc->y + pdsurf->ptl.y;
  126. ppdev = pdsurf->ppdev;
  127. }
  128. else
  129. {
  130. // Source is the screen.
  131. ptlSrc.x = pptlSrc->x;
  132. ptlSrc.y = pptlSrc->y;
  133. ppdev = (PPDEV) psoSrc->dhpdev;
  134. }
  135. //
  136. // Determine the destination type and adjust the destination offset.
  137. //
  138. if (psoTrg->iType == STYPE_DEVBITMAP)
  139. {
  140. PDSURF pdsurf = (PDSURF) psoTrg->dhsurf;
  141. ptlDest.x = prclTrg->left + pdsurf->ptl.x;
  142. ptlDest.y = prclTrg->top + pdsurf->ptl.y;
  143. }
  144. else
  145. {
  146. ptlDest.x = prclTrg->left;
  147. ptlDest.y = prclTrg->top;
  148. }
  149. //
  150. // Is there a translation table?
  151. // If so, we will attempt to load it into the chip. This also
  152. // points pulXlate at the color translation table, if there is one.
  153. //
  154. #if COLOR_TRANSLATE
  155. if (! bCacheXlateTable(ppdev, &pulXlate, psoTrg, psoSrc, pxlo,
  156. (BYTE)(ulDRAWBLTDEF&0xCC)) )
  157. #else
  158. if ( (pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL) )
  159. {
  160. pulXlate = NULL;
  161. }
  162. else if (pxlo->flXlate & XO_TABLE)
  163. {
  164. pulXlate = pxlo->pulXlate;
  165. }
  166. else
  167. {
  168. pulXlate = XLATEOBJ_piVector(pxlo);
  169. }
  170. if (pulXlate != NULL)
  171. #endif
  172. {
  173. // We must do software color translation.
  174. return DoDeviceToDeviceWithXlate(psoTrg, psoSrc, pulXlate, prclTrg,
  175. pptlSrc, ulDRAWBLTDEF);
  176. }
  177. //
  178. // if pulXlate == NULL, there is no color translation required.
  179. // if pulXlate != NULL, we will do hardware translation.
  180. //
  181. //
  182. // We only do screen to screen color translation in 8 bpp.
  183. //
  184. ASSERTMSG( ((pulXlate == NULL) || (ppdev->iBitmapFormat == BMF_8BPP)),
  185. "DoDeviceToDevice: Xlate with non-8bpp.\n");
  186. if ((pulXlate) && (ppdev->iBitmapFormat != BMF_8BPP))
  187. {
  188. return FALSE;
  189. }
  190. // Calculate the size of the blit.
  191. sizl.cx = prclTrg->right - prclTrg->left;
  192. sizl.cy = prclTrg->bottom - prclTrg->top;
  193. fStripePixels = (ulDRAWBLTDEF & 0x000F0000) | (pulXlate != NULL);
  194. if (fStripePixels)
  195. {
  196. // Calculate the number of pixels per tile and per SRAM line.
  197. switch (ppdev->iBitmapFormat)
  198. {
  199. case BMF_8BPP:
  200. tileSize = ppdev->lTileSize;
  201. maxStripeWidth = 120;
  202. break;
  203. case BMF_16BPP:
  204. tileSize = ppdev->lTileSize / 2;
  205. maxStripeWidth = 120 / 2;
  206. break;
  207. case BMF_24BPP:
  208. tileSize = ppdev->cxScreen;
  209. maxStripeWidth = max(ptlDest.x - ptlSrc.x, 120 / 3);
  210. break;
  211. case BMF_32BPP:
  212. tileSize = ppdev->lTileSize / 4;
  213. maxStripeWidth = 120 / 4;
  214. break;
  215. }
  216. }
  217. else
  218. {
  219. // Convert everything to bytes.
  220. ptlSrc.x *= ppdev->iBytesPerPixel;
  221. ptlDest.x *= ppdev->iBytesPerPixel;
  222. sizl.cx *= ppdev->iBytesPerPixel;
  223. tileSize = ppdev->lTileSize;
  224. maxStripeWidth = 120;
  225. }
  226. // Test vertical direction of blitting and set grDRAWBLTDEF register
  227. // accordingly.
  228. if (ptlSrc.y < ptlDest.y)
  229. {
  230. ptlSrc.y += sizl.cy - 1;
  231. ptlDest.y += sizl.cy - 1;
  232. ulDRAWBLTDEF |= 0x90100000;
  233. }
  234. else
  235. {
  236. ulDRAWBLTDEF |= 0x10100000;
  237. }
  238. // Test horizontal direction of blitting.
  239. if ( (ptlSrc.x >= ptlDest.x) || (ptlSrc.y != ptlDest.y) )
  240. {
  241. if (ptlSrc.x >= ptlDest.x)
  242. {
  243. // Blit to left.
  244. while (sizl.cx > 0)
  245. {
  246. // Calculate the width of this blit.
  247. LONG cx = sizl.cx;
  248. // Calculate how many pixels it is to the next source tile
  249. // boundary. Use lesser value.
  250. cx = min(cx, tileSize - (ptlSrc.x % tileSize));
  251. // Calculate how many pixels it is to the next destination tile
  252. // boundary. Use lesser value.
  253. cx = min(cx, tileSize - (ptlDest.x % tileSize));
  254. // Perform the blit.
  255. if (fFirst)
  256. {
  257. fFirst = FALSE;
  258. REQUIRE(9);
  259. LL_DRAWBLTDEF(ulDRAWBLTDEF, 0);
  260. if (fStripePixels)
  261. {
  262. LL_OP1(ptlSrc.x, ptlSrc.y);
  263. LL_OP0(ptlDest.x, ptlDest.y);
  264. if (pulXlate) // launch a color xlate BLT
  265. LL_BLTEXT_XLATE(8, cx, sizl.cy);
  266. else // Launch a regular BLT
  267. LL_BLTEXT(cx, sizl.cy);
  268. }
  269. else
  270. {
  271. LL_OP1_MONO(ptlSrc.x, ptlSrc.y);
  272. LL_OP0_MONO(ptlDest.x, ptlDest.y);
  273. LL_MBLTEXT(cx, sizl.cy);
  274. }
  275. }
  276. else if (pulXlate)
  277. {
  278. REQUIRE(7);
  279. LL_OP1(ptlSrc.x, ptlSrc.y);
  280. LL_OP0(ptlDest.x, ptlDest.y);
  281. LL_BLTEXT_XLATE(8, cx, sizl.cy);
  282. }
  283. else
  284. {
  285. REQUIRE(4);
  286. if (fStripePixels)
  287. {
  288. LL16(grOP1_opRDRAM.PT.X, ptlSrc.x);
  289. LL16(grOP0_opRDRAM.PT.X, ptlDest.x);
  290. LL16(grBLTEXT_XEX.PT.X, cx);
  291. }
  292. else
  293. {
  294. LL16(grOP1_opMRDRAM.PT.X, ptlSrc.x);
  295. LL16(grOP0_opMRDRAM.PT.X, ptlDest.x);
  296. LL16(grMBLTEXT_XEX.PT.X, cx);
  297. }
  298. }
  299. // Adjust the coordinates.
  300. ptlSrc.x += cx;
  301. ptlDest.x += cx;
  302. sizl.cx -= cx;
  303. }
  304. }
  305. else
  306. {
  307. // Blit to right.
  308. ptlSrc.x += sizl.cx;
  309. ptlDest.x += sizl.cx;
  310. while (sizl.cx > 0)
  311. {
  312. // Calculate the width of this blit.
  313. LONG cx = sizl.cx;
  314. // Calculate how many pixels it is to the next source tile
  315. // boundary. Use lesser value.
  316. if ((ptlSrc.x % tileSize) == 0)
  317. {
  318. cx = min(cx, tileSize);
  319. }
  320. else
  321. {
  322. cx = min(cx, ptlSrc.x % tileSize);
  323. }
  324. // Calculate how many pixels it is to the next destination tile
  325. // boundary. Use lesser value.
  326. if ((ptlDest.x % tileSize) == 0)
  327. {
  328. cx = min(cx, tileSize);
  329. }
  330. else
  331. {
  332. cx = min(cx, ptlDest.x % tileSize);
  333. }
  334. // Perform the blit.
  335. if (fFirst)
  336. {
  337. fFirst = FALSE;
  338. REQUIRE(9);
  339. LL_DRAWBLTDEF(ulDRAWBLTDEF, 0);
  340. if (fStripePixels)
  341. {
  342. LL_OP1(ptlSrc.x - cx, ptlSrc.y);
  343. LL_OP0(ptlDest.x - cx, ptlDest.y);
  344. if (pulXlate) // launch a color xlate BLT
  345. LL_BLTEXT_XLATE(8, cx, sizl.cy);
  346. else // Launch a regular BLT
  347. LL_BLTEXT(cx, sizl.cy);
  348. }
  349. else
  350. {
  351. LL_OP1_MONO(ptlSrc.x - cx, ptlSrc.y);
  352. LL_OP0_MONO(ptlDest.x - cx, ptlDest.y);
  353. LL_MBLTEXT(cx, sizl.cy);
  354. }
  355. }
  356. else if (pulXlate)
  357. {
  358. REQUIRE(7);
  359. LL_OP1(ptlSrc.x - cx, ptlSrc.y);
  360. LL_OP0(ptlDest.x - cx, ptlDest.y);
  361. LL_BLTEXT_XLATE(8, cx, sizl.cy);
  362. }
  363. else
  364. {
  365. REQUIRE(4);
  366. if (fStripePixels)
  367. {
  368. LL16(grOP1_opRDRAM.PT.X, ptlSrc.x - cx);
  369. LL16(grOP0_opRDRAM.PT.X, ptlDest.x - cx);
  370. LL16(grBLTEXT_XEX.PT.X, cx);
  371. }
  372. else
  373. {
  374. LL16(grOP1_opMRDRAM.PT.X, ptlSrc.x - cx);
  375. LL16(grOP0_opMRDRAM.PT.X, ptlDest.x - cx);
  376. LL16(grMBLTEXT_XEX.PT.X, cx);
  377. }
  378. }
  379. // Adjust the coordinates.
  380. ptlSrc.x -= cx;
  381. ptlDest.x -= cx;
  382. sizl.cx -= cx;
  383. }
  384. }
  385. }
  386. else
  387. {
  388. // Blit using SRAM.
  389. ptlSrc.x += sizl.cx;
  390. ptlDest.x += sizl.cx;
  391. while (sizl.cx > 0)
  392. {
  393. // Calculate the width of this blit. We must never overrun a single
  394. // SRAM cache line.
  395. LONG cx = min(sizl.cx, maxStripeWidth);
  396. // Calculate how many pixels it is to the next source tile
  397. // boundary. Use lesser value.
  398. cx = min(cx, ((ptlSrc.x - 1) % tileSize) + 1);
  399. // Calculate how many pixels it is to the next destination tile
  400. // boundary. Use lesser value.
  401. cx = min(cx, ((ptlDest.x - 1) % tileSize) + 1);
  402. // Do the blit.
  403. if (fFirst)
  404. {
  405. REQUIRE(9);
  406. LL_DRAWBLTDEF(ulDRAWBLTDEF, 0);
  407. if (fStripePixels)
  408. {
  409. LL_OP1(ptlSrc.x - cx, ptlSrc.y);
  410. LL_OP0(ptlDest.x - cx, ptlDest.y);
  411. if (pulXlate) // Launch a color xlate BLT
  412. LL_BLTEXT_XLATE(8, cx, sizl.cy);
  413. else // Launch a regular BLT
  414. LL_BLTEXT(cx, sizl.cy);
  415. }
  416. else
  417. {
  418. LL_OP1_MONO(ptlSrc.x - cx, ptlSrc.y);
  419. LL_OP0_MONO(ptlDest.x - cx, ptlDest.y);
  420. LL_MBLTEXT(cx, sizl.cy);
  421. }
  422. }
  423. else if (pulXlate)
  424. {
  425. REQUIRE(7);
  426. LL_OP1(ptlSrc.x - cx, ptlSrc.y);
  427. LL_OP0(ptlDest.x - cx, ptlDest.y);
  428. LL_BLTEXT_XLATE(8, cx, sizl.cy);
  429. }
  430. else
  431. {
  432. REQUIRE(4);
  433. if (fStripePixels)
  434. {
  435. LL16(grOP1_opRDRAM.PT.X, ptlSrc.x - cx);
  436. LL16(grOP0_opRDRAM.PT.X, ptlDest.x - cx);
  437. LL16(grBLTEXT_XEX.PT.X, cx);
  438. }
  439. else
  440. {
  441. LL16(grOP1_opMRDRAM.PT.X, ptlSrc.x - cx);
  442. LL16(grOP0_opMRDRAM.PT.X, ptlDest.x - cx);
  443. LL16(grMBLTEXT_XEX.PT.X, cx);
  444. }
  445. }
  446. // Adjust the coordinates.
  447. ptlSrc.x -= cx;
  448. ptlDest.x -= cx;
  449. sizl.cx -= cx;
  450. }
  451. }
  452. return(TRUE);
  453. }
  454. /*****************************************************************************\
  455. * DoDeviceToDeviceWithXlate
  456. *
  457. * This routine performs a ScreenToScreen, DeviceToScreen or ScreenToDevice
  458. * blit when there is a color translation table.
  459. * Color translation is done in software.
  460. *
  461. *
  462. * On entry: psoTrg Pointer to target surface object.
  463. * psoSrc Pointer to source surface object.
  464. * pulXlate Translation table.
  465. * prclTrg Destination rectangle.
  466. * pptlSrc Source offset.
  467. * ulDRAWBLTDEF Value for grDRAWBLTDEF register. This value has
  468. * the ROP and the brush flags.
  469. \*****************************************************************************/
  470. BOOL DoDeviceToDeviceWithXlate(
  471. SURFOBJ *psoTrg,
  472. SURFOBJ *psoSrc,
  473. ULONG *pulXlate,
  474. RECTL *prclTrg,
  475. POINTL *pptlSrc,
  476. ULONG ulDRAWBLTDEF
  477. )
  478. {
  479. POINTL ptlSrc, ptlDest;
  480. SIZEL sizl;
  481. PPDEV ppdev;
  482. BYTE* pjSrc;
  483. DWORD* pjHostData;
  484. LONG lDelta, lExtra, lLeadIn, i, n, tileSize, maxStripeWidth;
  485. // Determine the source type and adjust the source offset.
  486. if (psoSrc->iType == STYPE_DEVBITMAP)
  487. {
  488. // Source is a device bitmap.
  489. PDSURF pdsurf = (PDSURF) psoSrc->dhsurf;
  490. ptlSrc.x = pptlSrc->x + pdsurf->ptl.x;
  491. ptlSrc.y = pptlSrc->y + pdsurf->ptl.y;
  492. ppdev = pdsurf->ppdev;
  493. }
  494. else
  495. {
  496. // Source is the screen.
  497. ptlSrc.x = pptlSrc->x;
  498. ptlSrc.y = pptlSrc->y;
  499. ppdev = (PPDEV) psoSrc->dhpdev;
  500. }
  501. // Determine the destination type and adjust the destination offset.
  502. if (psoTrg->iType == STYPE_DEVBITMAP)
  503. {
  504. PDSURF pdsurf = (PDSURF) psoTrg->dhsurf;
  505. ptlDest.x = prclTrg->left + pdsurf->ptl.x;
  506. ptlDest.y = prclTrg->top + pdsurf->ptl.y;
  507. }
  508. else
  509. {
  510. ptlDest.x = prclTrg->left;
  511. ptlDest.y = prclTrg->top;
  512. }
  513. // We only support color translations in 8-bpp.
  514. if (ppdev->iBitmapFormat != BMF_8BPP)
  515. {
  516. return FALSE;
  517. }
  518. // Calculate the size of the blit.
  519. sizl.cx = prclTrg->right - prclTrg->left;
  520. sizl.cy = prclTrg->bottom - prclTrg->top;
  521. // Calculate the screen address.
  522. pjSrc = ppdev->pjScreen + ptlSrc.x + ptlSrc.y * ppdev->lDeltaScreen;
  523. lDelta = ppdev->lDeltaScreen;
  524. pjHostData = (DWORD*) ppdev->pLgREGS->grHOSTDATA;
  525. // Wait for the hardware to become idle.
  526. while (LLDR_SZ(grSTATUS) != 0) ;
  527. // DWORD align the source.
  528. lLeadIn = (DWORD)pjSrc & 3;
  529. pjSrc -= lLeadIn;
  530. n = (sizl.cx + lLeadIn + 3) >> 2;
  531. // Test for overlapping.
  532. if (ptlSrc.y < ptlDest.y)
  533. {
  534. // Negative direction.
  535. pjSrc += (sizl.cy - 1) * lDelta;
  536. ptlDest.y += sizl.cy - 1;
  537. lDelta = -lDelta;
  538. REQUIRE(9);
  539. LL_DRAWBLTDEF(ulDRAWBLTDEF | 0x90200000, 0);
  540. }
  541. else if (ptlSrc.y > ptlDest.y)
  542. {
  543. // Positive direction.
  544. REQUIRE(9);
  545. LL_DRAWBLTDEF(ulDRAWBLTDEF | 0x10200000, 0);
  546. }
  547. else
  548. {
  549. // Maybe horizontal overlap, punt call to GDI anyway.
  550. return(FALSE);
  551. }
  552. #if ! DRIVER_5465
  553. // Get the number of extra DWORDS per line for the HOSTDATA hardware
  554. // bug.
  555. if (ppdev->dwLgDevID == CL_GD5462)
  556. {
  557. if (MAKE_HD_INDEX(sizl.cx, lLeadIn, ptlDest.x) == 3788)
  558. {
  559. // We have a problem with the HOSTDATA TABLE.
  560. // Punt till we can figure it out.
  561. return FALSE;
  562. }
  563. lExtra =
  564. ExtraDwordTable[MAKE_HD_INDEX(sizl.cx, lLeadIn, ptlDest.x)];
  565. }
  566. else
  567. lExtra = 0;
  568. #endif
  569. // Start the blit.
  570. LL_OP1_MONO(lLeadIn, 0);
  571. LL_OP0(ptlDest.x, ptlDest.y);
  572. LL_BLTEXT(sizl.cx, sizl.cy);
  573. while (sizl.cy--)
  574. {
  575. BYTE *p = pjSrc;
  576. BYTE pixel[4];
  577. for (i = 0; i < n; i++)
  578. {
  579. pixel[0] = (BYTE) pulXlate[p[0]];
  580. pixel[1] = (BYTE) pulXlate[p[1]];
  581. pixel[2] = (BYTE) pulXlate[p[2]];
  582. pixel[3] = (BYTE) pulXlate[p[3]];
  583. p += 4;
  584. REQUIRE(1);
  585. *pjHostData = *(DWORD*) pixel;
  586. }
  587. #if !DRIVER_5465
  588. // Now, write the extra DWORDS.
  589. REQUIRE(lExtra);
  590. for (i = 0; i < lExtra; i++)
  591. {
  592. LL32(grHOSTDATA[i], 0);
  593. }
  594. #endif
  595. // Next line.
  596. pjSrc += lDelta;
  597. }
  598. // Return okay.
  599. return(TRUE);
  600. }