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.

2035 lines
64 KiB

  1. /*============================ Module Header ==========================*\
  2. *
  3. * Module Name: HOST2SCN.c
  4. * Author: Noel VanHook
  5. * Date: Oct. 10, 1995
  6. * Purpose: Handles HOST to SCREEN BLTs
  7. *
  8. * Copyright (c) 1995 Cirrus Logic, Inc.
  9. *
  10. * $Log: X:/log/laguna/nt35/displays/cl546x/HOST2SCN.C $
  11. *
  12. * Rev 1.7 Mar 04 1998 15:27:16 frido
  13. * Added new shadow macros.
  14. *
  15. * Rev 1.6 Nov 03 1997 15:43:52 frido
  16. * Added REQUIRE and WRITE_STRING macros.
  17. *
  18. \*=====================================================================*/
  19. #include "precomp.h"
  20. #if BUS_MASTER
  21. extern ULONG ulXlate[16]; // See COPYBITS.C
  22. /*****************************************************************************\
  23. * *
  24. * 8 - B P P *
  25. * *
  26. \*****************************************************************************/
  27. /*****************************************************************************\
  28. * BusMasterBufferedHost8ToDevice
  29. *
  30. * This routine performs a HostToScreen or HostToDevice blit. The host data
  31. * can be either monochrome, 4-bpp, or 8-bpp. Color translation is supported.
  32. *
  33. * Host data is read from the host bitmap and stored in a common buffer.
  34. * The HOSTXY unit on the chip is used to transfer the data from the common
  35. * buffer to the screen.
  36. *
  37. * On entry: psoTrg Pointer to target surface object.
  38. * psoSrc Pointer to source surface object.
  39. * pxlo Pointer to translation object.
  40. * prclTrg Destination rectangle.
  41. * pptlSrc Source offset.
  42. * ulDRAWBLTDEF Value for grDRAWBLTDEF register. This value has
  43. * the ROP and the brush flags.
  44. \*****************************************************************************/
  45. BOOL BusMasterBufferedHost8ToDevice(
  46. SURFOBJ *psoTrg,
  47. SURFOBJ *psoSrc,
  48. XLATEOBJ *pxlo,
  49. RECTL *prclTrg,
  50. POINTL *pptlSrc,
  51. ULONG ulDRAWBLTDEF
  52. )
  53. {
  54. POINTL ptlDest, ptlSrc;
  55. SIZEL sizl;
  56. PPDEV ppdev;
  57. PBYTE pBits;
  58. LONG lDelta, i, j, n, lLeadIn, lExtra;
  59. ULONG *pulXlate;
  60. FLONG flXlate;
  61. ULONG CurrentBuffer,
  62. BufPhysAddr;
  63. long ScanLinesPerBuffer,
  64. ScanLinesThisBuffer;
  65. PDWORD pHostData;
  66. // Calculate the source offset.
  67. ptlSrc.x = pptlSrc->x;
  68. ptlSrc.y = pptlSrc->y;
  69. //
  70. // If the destination is a device bitmap, then our destination coordinates
  71. // are relative the the upper left corner of the bitmap. The chip expects
  72. // destination coordinates relative to to screen(0,0).
  73. //
  74. // Determine the destination type and calculate the destination offset.
  75. //
  76. if (psoTrg->iType == STYPE_DEVBITMAP)
  77. {
  78. PDSURF pdsurf = (PDSURF) psoTrg->dhsurf;
  79. ptlDest.x = prclTrg->left + pdsurf->ptl.x;
  80. ptlDest.y = prclTrg->top + pdsurf->ptl.y;
  81. ppdev = pdsurf->ppdev;
  82. }
  83. else
  84. {
  85. ptlDest.x = prclTrg->left;
  86. ptlDest.y = prclTrg->top;
  87. ppdev = (PPDEV) psoTrg->dhpdev;
  88. }
  89. // Calculate the size of the blit.
  90. sizl.cx = prclTrg->right - prclTrg->left;
  91. sizl.cy = prclTrg->bottom - prclTrg->top;
  92. //
  93. // Get the source variables and offset into source bits.
  94. // point pBits at the first scan line in the source.
  95. //
  96. lDelta = psoSrc->lDelta;
  97. pBits = (PBYTE)psoSrc->pvScan0 + (ptlSrc.y * lDelta);
  98. // Get the pointer to the translation table.
  99. flXlate = pxlo ? pxlo->flXlate : XO_TRIVIAL;
  100. if (flXlate & XO_TRIVIAL)
  101. {
  102. pulXlate = NULL;
  103. }
  104. else if (flXlate & XO_TABLE)
  105. {
  106. pulXlate = pxlo->pulXlate;
  107. }
  108. else if (pxlo->iSrcType == PAL_INDEXED)
  109. {
  110. pulXlate = XLATEOBJ_piVector(pxlo);
  111. }
  112. else
  113. {
  114. // Some kind of translation we don't handle.
  115. return FALSE;
  116. }
  117. // -----------------------------------------------------------------------
  118. //
  119. // Test for monochrome source.
  120. //
  121. // ------------------------------------------------------------------------
  122. if (psoSrc->iBitmapFormat == BMF_1BPP)
  123. {
  124. ULONG bgColor, fgColor;
  125. PDWORD pHostData = (PDWORD) ppdev->pLgREGS->grHOSTDATA;
  126. // Set background and foreground colors.
  127. if (pulXlate == NULL)
  128. {
  129. bgColor = 0x00000000;
  130. fgColor = 0xFFFFFFFF;
  131. }
  132. else
  133. {
  134. bgColor = pulXlate[0];
  135. fgColor = pulXlate[1];
  136. // Expand the colors.
  137. bgColor |= bgColor << 8;
  138. fgColor |= fgColor << 8;
  139. bgColor |= bgColor << 16;
  140. fgColor |= fgColor << 16;
  141. }
  142. //
  143. // Special case: when we are expanding monochrome sources and we
  144. // already have a colored brush, we must make sure the monochrome color
  145. // translation can be achived by setting the saturation bit (expanding
  146. // 0's to 0 and 1's to 1). If the monochrome source also requires color
  147. // translation, we simply punt this blit back to GDI.
  148. //
  149. if (ulDRAWBLTDEF & 0x00040000)
  150. {
  151. if ( (bgColor == 0x00000000) && (fgColor == 0xFFFFFFFF) )
  152. {
  153. // Enable saturation for source (OP1).
  154. ulDRAWBLTDEF |= 0x00008000;
  155. }
  156. #if SOLID_CACHE
  157. else if ( ((ulDRAWBLTDEF & 0x000F0000) == 0x00070000) &&
  158. ppdev->Bcache )
  159. {
  160. CacheSolid(ppdev);
  161. ulDRAWBLTDEF ^= (0x00070000 ^ 0x00090000);
  162. REQUIRE(4);
  163. LL_BGCOLOR(bgColor, 2);
  164. LL_FGCOLOR(fgColor, 2);
  165. }
  166. #endif
  167. else
  168. {
  169. // Punt this call to the GDI.
  170. return(FALSE);
  171. }
  172. }
  173. else
  174. {
  175. REQUIRE(4);
  176. LL_BGCOLOR(bgColor, 2);
  177. LL_FGCOLOR(fgColor, 2);
  178. }
  179. // Calculate the source parameters. We are going to DWORD adjust the
  180. // source, so we must setup the source phase.
  181. lLeadIn = ptlSrc.x & 31;
  182. pBits += (ptlSrc.x >> 3) & ~3;
  183. n = (sizl.cx + lLeadIn + 31) >> 5;
  184. // Setup the Laguna registers for the blit. We also set the bit swizzle
  185. // bit in the grCONTROL register.
  186. ppdev->grCONTROL |= SWIZ_CNTL;
  187. REQUIRE(10);
  188. LL16(grCONTROL, ppdev->grCONTROL);
  189. LL_DRAWBLTDEF(ulDRAWBLTDEF | 0x10600000, 0);
  190. // Start the blit.
  191. LL_OP1_MONO(lLeadIn, 0);
  192. LL_OP0(ptlDest.x, ptlDest.y);
  193. LL_BLTEXT(sizl.cx, sizl.cy);
  194. // Copy all the bits to the screen, 32-bits at a time. We don't have to
  195. // worry about crossing any boundary since NT is always DWORD aligned.
  196. while (sizl.cy--)
  197. {
  198. WRITE_STRING(pBits, n);
  199. pBits += lDelta;
  200. }
  201. // Disable the swizzle bit in the grCONTROL register.
  202. ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
  203. LL16(grCONTROL, ppdev->grCONTROL);
  204. }
  205. // -----------------------------------------------------------------------
  206. //
  207. // Test for 4-bpp source.
  208. //
  209. // -----------------------------------------------------------------------
  210. else if (psoSrc->iBitmapFormat == BMF_4BPP)
  211. {
  212. // Calculate the source parameters. We are going to BYTE adjust the
  213. // source, so we also set the source phase.
  214. lLeadIn = ptlSrc.x & 1;
  215. pBits += ptlSrc.x >> 1;
  216. n = sizl.cx + (ptlSrc.x & 1);
  217. // Get the number of extra DWORDS per line for the HOSTDATA hardware
  218. // bug.
  219. lExtra = ExtraDwordTable[MAKE_HD_INDEX(sizl.cx, lLeadIn, ptlDest.x)];
  220. // Start the blit.
  221. REQUIRE(9);
  222. LL_DRAWBLTDEF(ulDRAWBLTDEF | 0x10200000, 0);
  223. LL_OP1_MONO(lLeadIn, 0);
  224. LL_OP0(ptlDest.x, ptlDest.y);
  225. LL_BLTEXT(sizl.cx, sizl.cy);
  226. // If there is no translation table, use the default translation table.
  227. if (pulXlate == NULL)
  228. {
  229. pulXlate = ulXlate;
  230. }
  231. // Now we are ready to copy all the pixels to the hardware.
  232. while (sizl.cy--)
  233. {
  234. BYTE *p = pBits;
  235. BYTE data[4];
  236. // First, we convert 4 pixels at a time to create a 32-bit value to
  237. // write to the hardware.
  238. for (i = n; i >= 4; i -= 4)
  239. {
  240. data[0] = (BYTE) pulXlate[p[0] >> 4];
  241. data[1] = (BYTE) pulXlate[p[0] & 0x0F];
  242. data[2] = (BYTE) pulXlate[p[1] >> 4];
  243. data[3] = (BYTE) pulXlate[p[1] & 0x0F];
  244. REQUIRE(1);
  245. LL32(grHOSTDATA[0], *(DWORD *)data);
  246. p += 2;
  247. }
  248. // Now, write any remaining pixels.
  249. switch (i)
  250. {
  251. case 1:
  252. REQUIRE(1);
  253. LL32(grHOSTDATA[0], pulXlate[p[0] >> 4]);
  254. break;
  255. case 2:
  256. data[0] = (BYTE) pulXlate[p[0] >> 4];
  257. data[1] = (BYTE) pulXlate[p[0] & 0x0F];
  258. REQUIRE(1);
  259. LL32(grHOSTDATA[0], *(DWORD *)data);
  260. break;
  261. case 3:
  262. data[0] = (BYTE) pulXlate[p[0] >> 4];
  263. data[1] = (BYTE) pulXlate[p[0] & 0x0F];
  264. data[2] = (BYTE) pulXlate[p[1] >> 4];
  265. REQUIRE(1);
  266. LL32(grHOSTDATA[0], *(DWORD *)data);
  267. break;
  268. }
  269. // Now, write the extra DWORDS.
  270. REQUIRE(lExtra);
  271. for (i = 0; i < lExtra; i++)
  272. {
  273. LL32(grHOSTDATA[0], 0);
  274. }
  275. // Next line.
  276. pBits += lDelta;
  277. }
  278. }
  279. // -----------------------------------------------------------------------
  280. //
  281. // Source is in same color depth as screen (8 bpp).
  282. //
  283. // -----------------------------------------------------------------------
  284. else
  285. {
  286. DISPDBG((1, " * * * * Doing bus mastered SRCCPY. * * * * \n"));
  287. // If we have invalid translation flags, punt the blit.
  288. if (flXlate & 0x10)
  289. return(FALSE);
  290. //
  291. // pBits points to the first host bitmap scan line that will
  292. // be part of the BLT.
  293. // This function relies on the fact that in NT land, scanlines always
  294. // begin on a DWORD boundry in system memory.
  295. //
  296. ASSERTMSG( ((((ULONG)pBits) % 4) == 0),
  297. "Scanline doesn't begin on a DWORD boundry.\n");
  298. // Now point pBits at the first host bitmap pixel to be
  299. // transferred to the screen.
  300. pBits += ptlSrc.x; // pBits = First pixel of source bitmap.
  301. //
  302. // The Intel CPU doesn't like to transfer unaligned DWORDs.
  303. //
  304. // Just because the first pixel in a host bitmap scan line
  305. // is DWORD aligned, doesn't mean that the first source pixel
  306. // in this BLT is DWORD alinged. We may be starting with
  307. // pixel 3 or something.
  308. // If our first pixel is in the middle of a DWORD, we need to know
  309. // where in the DWORD it lives.
  310. // For example:
  311. // If our first pixel is 0, then it lives at the start of a DWORD.
  312. // If our first pixel is 3, then it lives at byte 3 in the DWORD.
  313. // If our first pixel is 6, then it lives at byte 2 in the DWORD.
  314. //
  315. lLeadIn = (DWORD)pBits & 3;
  316. // If the first pixel of the source data doesn't fall on a
  317. // DWORD boundry, adjust it to the left until it does.
  318. // We can do this because of the ASSERT we made above.
  319. // We will instruct the chip to ignore the 'lead in' pixels
  320. // at the start of each scan line.
  321. pBits -= lLeadIn;
  322. // Now figure out how many dwords there are in each scan line.
  323. n = (sizl.cx + lLeadIn + 3) >> 2;
  324. //
  325. // We will split the BLT into pieces that can fit into our common
  326. // buffer. We are guarenteed by the miniport that each buffer is big
  327. // enough to fit at least one scan line.
  328. //
  329. // One optimization is if bitmap pitch = blt width, glue the
  330. // scan lines together.
  331. //
  332. ScanLinesPerBuffer = ppdev->BufLength / (n*4);
  333. CurrentBuffer = 1;
  334. //
  335. // Now BLT the bitmap one buffer at a time.
  336. //
  337. // Enable the HOST XY unit.
  338. LL32(grHXY_HOST_CRTL_3D, 1);
  339. LL32(grHXY_BASE1_OFFSET1_3D, 0);
  340. // Setup the Laguna registers.
  341. REQUIRE(4);
  342. LL_DRAWBLTDEF(ulDRAWBLTDEF | 0x10200000, 0);
  343. LL_OP1_MONO(lLeadIn, 0);
  344. while (1) // Each loop transfers one buffer.
  345. {
  346. DISPDBG((1, " Filling buffer.\n"));
  347. //
  348. // Select the buffer we will use for this BLT.
  349. //
  350. if (CurrentBuffer)
  351. {
  352. pHostData = (PDWORD) ppdev->Buf1VirtAddr;
  353. BufPhysAddr = (ULONG) ppdev->Buf1PhysAddr;
  354. }
  355. else
  356. {
  357. pHostData = (PDWORD) ppdev->Buf2VirtAddr;
  358. BufPhysAddr = (ULONG) ppdev->Buf2PhysAddr;
  359. }
  360. // Is there enough bitmap left to fill an entire buffer?
  361. if (ScanLinesPerBuffer > sizl.cy)
  362. ScanLinesThisBuffer = sizl.cy; // No.
  363. else
  364. ScanLinesThisBuffer = ScanLinesPerBuffer;
  365. //
  366. // Now fill the buffer with bitmap data.
  367. //
  368. j = ScanLinesThisBuffer; // Counter for scan lines.
  369. // Test for color translation.
  370. if (pulXlate == NULL)
  371. {
  372. while (j--) // Loop for each scan line.
  373. {
  374. // Copy all data in 32-bit. We don't have to worry about
  375. // crossing any boundaries, since within NT everything is
  376. // DWORD aligned.
  377. #if defined(i386) && INLINE_ASM
  378. _asm
  379. {
  380. mov edi, pHostData
  381. mov esi, pBits
  382. mov ecx, n
  383. rep movsd
  384. }
  385. #else
  386. for (i = 0; i < n; i++)
  387. pHostData[i] = pBits[i];
  388. #endif
  389. // Next line in source.
  390. pBits += lDelta;
  391. // Next line in buffer.
  392. pHostData += n;
  393. }
  394. }
  395. else
  396. {
  397. DWORD *p;
  398. while (j--) // Loop for each scan line.
  399. {
  400. // p = pointer to source scan line
  401. p = (DWORD *)pBits;
  402. // Copy the scan line one DWORD at a time.
  403. for (i = 0; i < n; i++)
  404. {
  405. // We copy 4 pixels to fill an entire 32-bit DWORD.
  406. union
  407. {
  408. BYTE byte[4];
  409. DWORD dw;
  410. } hostdata;
  411. // Read a DWORD from the source.
  412. hostdata.dw = *p++;
  413. // Color convert it.
  414. hostdata.byte[0] = (BYTE) pulXlate[hostdata.byte[0]];
  415. hostdata.byte[1] = (BYTE) pulXlate[hostdata.byte[1]];
  416. hostdata.byte[2] = (BYTE) pulXlate[hostdata.byte[2]];
  417. hostdata.byte[3] = (BYTE) pulXlate[hostdata.byte[3]];
  418. // Write it to the buffer.
  419. *pHostData++ = hostdata.dw;
  420. }
  421. // Move to next line in source.
  422. pBits += lDelta;
  423. }
  424. }
  425. //
  426. // The common buffer is full, now BLT it.
  427. //
  428. //
  429. // Wait until HOST XY unit goes idle.
  430. //
  431. DISPDBG((1, " Waiting for HOSTXY idle.\n"));
  432. do {
  433. i = LLDR_SZ (grPF_STATUS_3D);
  434. } while (i & 0x80);
  435. //
  436. // Wait until 2D unit goes idle.
  437. //
  438. DISPDBG((1, " Waiting for 2D idle.\n"));
  439. do {
  440. i = LLDR_SZ (grSTATUS);
  441. } while (i);
  442. //
  443. // Program 2D Blitter.
  444. //
  445. DISPDBG((1, " Blitting buffer.\n"));
  446. // Start the blit.
  447. REQUIRE(5);
  448. LL_OP0(ptlDest.x, ptlDest.y);
  449. LL_BLTEXT(sizl.cx, ScanLinesThisBuffer);
  450. //
  451. // Program HostXY unit.
  452. //
  453. // Write host address page.
  454. LL32(grHXY_BASE1_ADDRESS_PTR_3D, (BufPhysAddr&0xFFFFF000));
  455. // Write host address offset.
  456. LL32(grHXY_BASE1_OFFSET0_3D, (BufPhysAddr&0x00000FFF));
  457. if (0)
  458. {
  459. // Write the length of the host data (in bytes)
  460. // This starts the Host XY unit.
  461. LL32(grHXY_BASE1_LENGTH_3D, (n*ScanLinesThisBuffer*4));
  462. }
  463. else
  464. {
  465. int i;
  466. PDWORD BufVirtAddr;
  467. if (CurrentBuffer)
  468. BufVirtAddr = (PDWORD) ppdev->Buf1VirtAddr;
  469. else
  470. BufVirtAddr = (PDWORD) ppdev->Buf2VirtAddr;
  471. WRITE_STRING(BufVirtAddr, n * ScanLinesThisBuffer);
  472. }
  473. //
  474. // Get ready to do the next buffer.
  475. //
  476. //
  477. // Wait until HOST XY unit goes idle.
  478. //
  479. DISPDBG((1, " Waiting for HOSTXY idle.\n"));
  480. do {
  481. i = LLDR_SZ (grPF_STATUS_3D);
  482. } while (i & 0x80);
  483. //
  484. // Wait until 2D unit goes idle.
  485. //
  486. DISPDBG((1, " Waiting for 2D idle.\n"));
  487. do {
  488. i = LLDR_SZ (grSTATUS);
  489. } while (i);
  490. //
  491. // Subtract the amount we're doing in this buffer from the
  492. // total amount we have to do.
  493. //
  494. sizl.cy -= ScanLinesThisBuffer;
  495. ptlDest.y += ScanLinesThisBuffer;
  496. //
  497. // Have we done the entire host bitmap?
  498. //
  499. if (sizl.cy == 0)
  500. break;
  501. DISPDBG((1, " Swapping buffers.\n"));
  502. // Swap buffers.
  503. // CurrentBuffer = !(CurrentBuffer);
  504. if (CurrentBuffer)
  505. CurrentBuffer = 0;
  506. else
  507. CurrentBuffer = 1;
  508. } // End loop. Do next buffer.
  509. //
  510. // Wait until HOST XY unit goes idle.
  511. //
  512. DISPDBG((1, " Waiting for final idle.\n"));
  513. do {
  514. i = LLDR_SZ (grPF_STATUS_3D);
  515. } while (i & 0x80);
  516. DISPDBG((1, " Done.\n"));
  517. }
  518. return(TRUE);
  519. }
  520. #if 0
  521. #define H2S_DBG_LEVEL 1
  522. //
  523. // In an attempt to trace the problems with the FIFO, we supply a few
  524. // macros that will allow us to easily try different FIFO stratagies.
  525. //
  526. //
  527. // Certian parts of our driver are optimized for the i386.
  528. // They have slower counterparts for non i386 machines.
  529. //
  530. #if defined(i386)
  531. #define USE_DWORD_CAST 1 // i386 can address a DWORD anywhere.
  532. #define USE_REP_MOVSD 0 // We could use a bit of in-line assembler.
  533. #else
  534. #define USE_DWORD_CAST 0
  535. #define USE_REP_MOVSD 0
  536. #endif
  537. //
  538. // All the BLT functions take the same parameters.
  539. //
  540. typedef BOOL BLTFN(
  541. PPDEV ppdev,
  542. RECTL* DestRect,
  543. SURFOBJ* psoSrc,
  544. POINTL* pptlSrc,
  545. BRUSHOBJ* pbo,
  546. POINTL* pptlBrush,
  547. ULONG fg_rop,
  548. XLATEOBJ* pxlo,
  549. CLIPOBJ* pco);
  550. //
  551. // Top level BLT functions.
  552. //
  553. BLTFN MonoHostToScreen;
  554. BLTFN Color8HostToScreen, Color16HostToScreen,
  555. Color24HostToScreen, Color32HostToScreen;
  556. //
  557. // Clipping stuff
  558. //
  559. VOID BltClip(
  560. PPDEV ppdev,
  561. CLIPOBJ* pco,
  562. RECTL* DestRect,
  563. SURFOBJ* psoSrc,
  564. POINTL* pptlSrc,
  565. BRUSHOBJ* pbo,
  566. POINTL* pptlBrush,
  567. ULONG fg_rop,
  568. XLATEOBJ* pxlo,
  569. BLTFN* pDoBlt);
  570. //
  571. // Bottom level BLT functions.
  572. //
  573. BLTFN HW1HostToScreen, HW8HostToScreen, HW16HostToScreen, HW32HostToScreen;
  574. //
  575. // 8 bpp HostToScreen helper functions.
  576. //
  577. VOID DoAlignedH2SBlt(
  578. PPDEV ppdev,
  579. ULONG ulDstX, ULONG ulDstY,
  580. ULONG ulExtX, ULONG ulExtY,
  581. UCHAR *pucData, ULONG deltaX);
  582. VOID DoNarrowH2SBlt(
  583. PPDEV ppdev,
  584. ULONG ulDstX, ULONG ulDstY,
  585. ULONG ulExtX, ULONG ulExtY,
  586. UCHAR *pucImageD, ULONG deltaX);
  587. //
  588. // Driver profiling stuff.
  589. // Gets compiled out in a free bulid.
  590. // Declaring puntcode as a global violates display driver rules, but the
  591. // emulator was chock full of globals anyway, and besides we won't ever
  592. // release a version with this enabled.
  593. //
  594. #if PROFILE_DRIVER
  595. void DumpInfo(int acc, PPDEV ppdev, SURFOBJ* psoSrc, SURFOBJ* psoDest,
  596. ULONG fg_rop, ULONG bg_rop, CLIPOBJ* pco, BRUSHOBJ* pbo, XLATEOBJ* pxlo);
  597. extern int puntcode;
  598. #define PUNTCODE(x) puntcode = x;
  599. #else
  600. #define DumpInfo(acc,ppdev,psoSrc,psoDest,fg_rop,bg_rop,pco,pbo,pxlo)
  601. #define PUNTCODE(x)
  602. #endif
  603. // *************************************************************************
  604. //
  605. // MonoHostToScreen()
  606. //
  607. // Handles Monochrome Host to screen blts.
  608. // Called by op1BLT() and op1op2BLT
  609. // op1BLT() calls this routine with pbo = NULL.
  610. // op1op2BLT calls it with pbo = current brush.
  611. //
  612. // This is the top level function. This function verifies parameters,
  613. // and decides if we should punt or not.
  614. //
  615. // The BLT is then handed off to the clipping function. The clipping
  616. // function is also given a pointer to the lower level BLT function
  617. // HW1HostToScreen(), which will complete the clipped BLT.
  618. //
  619. // This function is the last chance to decide to punt. The clipping
  620. // functions and the lower level HW1HostToScreen() function aren't
  621. // allowed to punt.
  622. //
  623. // Return TRUE if we can do the BLT,
  624. // Return FALSE to punt it back to GDI.
  625. //
  626. // *************************************************************************
  627. BOOL MonoHostToScreen(
  628. PPDEV ppdev,
  629. RECTL* prclDest,
  630. SURFOBJ* psoSrc,
  631. POINTL* pptlSrc,
  632. BRUSHOBJ* pbo,
  633. POINTL* pptlBrush,
  634. ULONG fg_rop,
  635. XLATEOBJ* pxlo,
  636. CLIPOBJ* pco)
  637. {
  638. PULONG pulXlate;
  639. ULONG fg, bg, bltdef = 0x1160;
  640. DISPDBG(( H2S_DBG_LEVEL,"DrvBitBlt: MonoHostToScreen Entry.\n"));
  641. //
  642. // Make sure source is a standard top-down bitmap.
  643. //
  644. if ( (psoSrc->iType != STYPE_BITMAP) ||
  645. (!(psoSrc->fjBitmap & BMF_TOPDOWN)) )
  646. { PUNTCODE(4); return FALSE; }
  647. //
  648. // We don't do brushes with mono src.
  649. //
  650. if (pbo)
  651. { PUNTCODE(7); return FALSE; }
  652. //
  653. // Handle color translation.
  654. //
  655. if (pxlo == NULL) // Mono source requires translation.
  656. {
  657. PUNTCODE(6);
  658. return FALSE;
  659. }
  660. else if (pxlo->flXlate & XO_TRIVIAL)
  661. {
  662. // For trivial translation we don't need a Xlate table.
  663. fg = 1;
  664. bg = 0;
  665. }
  666. else
  667. {
  668. // Get the Xlate table.
  669. if (pxlo->flXlate & XO_TABLE)
  670. pulXlate = pxlo->pulXlate;
  671. else if (pxlo->iSrcType == PAL_INDEXED)
  672. {
  673. pulXlate = XLATEOBJ_piVector(pxlo);
  674. }
  675. else
  676. {
  677. // Some kind of translation we don't handle.
  678. return FALSE;
  679. }
  680. // Translate the colors.
  681. fg = ExpandColor(pulXlate[1],ppdev->ulBitCount);
  682. bg = ExpandColor(pulXlate[0],ppdev->ulBitCount);
  683. }
  684. REQUIRE(4);
  685. LL_FGCOLOR(fg, 2);
  686. LL_BGCOLOR(bg, 2);
  687. //
  688. // Turn swizzle on.
  689. //
  690. ppdev->grCONTROL |= SWIZ_CNTL;
  691. LL16(grCONTROL, ppdev->grCONTROL);
  692. //
  693. // Set function and ROP code.
  694. //
  695. LL_DRAWBLTDEF(((DWORD)bltdef << 16) | fg_rop, 2);
  696. //
  697. // Clip the BLT.
  698. // The clipping function will call HW1HostToScreen() to finish the BLT.
  699. //
  700. if ((pco == 0) || (pco->iDComplexity==DC_TRIVIAL))
  701. HW1HostToScreen(ppdev, prclDest, psoSrc, pptlSrc,
  702. pbo, pptlBrush, fg_rop, pxlo, pco);
  703. else
  704. BltClip(ppdev, pco, prclDest, psoSrc, pptlSrc,
  705. pbo, pptlBrush, fg_rop, pxlo, &HW1HostToScreen);
  706. //
  707. // Turn swizzle off
  708. //
  709. ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
  710. LL16(grCONTROL, ppdev->grCONTROL);
  711. return TRUE;
  712. }
  713. // ************************************************************************* //
  714. // //
  715. // HW1HostToScreen() //
  716. // //
  717. // This function is responsible for actually talking to the chip. //
  718. // At this point we are required to handle the BLT, so we must return TRUE. //
  719. // All decisions as to whether to punt or not must be made in the top level //
  720. // function MonoHostToScreen(). //
  721. // //
  722. // This function is called from BltClip() through a pointer set by //
  723. // MonoHostToScreen(). //
  724. // //
  725. // ************************************************************************* //
  726. BOOL HW1HostToScreen(
  727. PPDEV ppdev,
  728. RECTL* prclDest,
  729. SURFOBJ* psoSrc,
  730. POINTL* pptlSrc,
  731. BRUSHOBJ* pbo,
  732. POINTL* pptlBrush,
  733. ULONG fg_rop,
  734. XLATEOBJ* pxlo,
  735. CLIPOBJ* pco)
  736. {
  737. INT x, y, i;
  738. INT bltWidth, bltHeight, phase;
  739. PBYTE psrc;
  740. DWORD hostdata;
  741. char *phd = (char *)&hostdata;
  742. DISPDBG(( H2S_DBG_LEVEL,"DrvBitBlt: HW1HostToScreen Entry.\n"));
  743. // Calculate BLT size in pixels.
  744. bltWidth = (prclDest->right - prclDest->left);
  745. bltHeight = (prclDest->bottom - prclDest->top);
  746. //
  747. // Phase
  748. // For 1bpp sources, we must be concerned with phase.
  749. // Phase is the number of pixels to skip in the first dword
  750. // of a scan line. For instance, if our BLT has a Src_X of 10,
  751. // we take our first dword starting at second byte in the src
  752. // scan line, and set our phase to 2 to indicate that we skip
  753. // the first two pixels.
  754. //
  755. phase = pptlSrc->x % 8;
  756. REQUIRE(7);
  757. LL_OP1_MONO(phase,0);
  758. //
  759. // Calculate blt width in BYTESs.
  760. // When calculating the number of BYTES per line, we need to
  761. // include the unused pixels at the start of the first BYTE
  762. //
  763. bltWidth += phase;
  764. // Divide bltWidth by 8 pixels per BYTE.
  765. // Account for extra partial BYTE if bltWidth isn't evenly
  766. // divisible by 8.
  767. bltWidth = (bltWidth+7) / 8;
  768. //
  769. // Set psrc to point to first pixel in source.
  770. //
  771. psrc = psoSrc->pvScan0; // Start of surface.
  772. psrc += (psoSrc->lDelta * pptlSrc->y); // Start of scanline.
  773. psrc += (pptlSrc->x / 8); // Starting pixel in scanline.
  774. // Set up the chip.
  775. LL_OP0 (prclDest->left, prclDest->top);
  776. LL_BLTEXT ((prclDest->right - prclDest->left), bltHeight);
  777. // For each scan line in the source rectangle.
  778. for (y=0; y<bltHeight; ++y)
  779. {
  780. //
  781. // Supply the HOSTDATA for this scan line.
  782. // We do this by reading it one byte at a time, and packing it into a
  783. // DWORD, which we write to the chip when it gets full.
  784. // It sound's inefficent, but a general purpose solution that
  785. // does only aligned DWORD accesses on both the host and the chip would
  786. // require lots of special casing around the first and last DWORD.
  787. // Combine that with the fact that most Mono-to-Color BLTS are
  788. // less than 2 dwords wide, and this simpler solution becomes
  789. // more attractive.
  790. //
  791. #if 1
  792. WRITE_STRING(psrc, (bltWidth + 3) / 4);
  793. #else
  794. i=0; // counter to tell us when our DWORD is full.
  795. hostdata=0; // The DWORD we will be filling with hostdata.
  796. // pdh is a char pointer that points to the start
  797. // of the dword we are filling up.
  798. for (x=0; x<bltWidth; ) // For each byte in the scan line...
  799. {
  800. #if (USE_DWORD_CAST)
  801. if ( (x + 4) <= bltWidth)
  802. {
  803. REQUIRE(1);
  804. LL32 (grHOSTDATA[0], *(DWORD*)(&psrc[x]));
  805. x += 4;
  806. }
  807. else
  808. #endif
  809. {
  810. phd[i++] = psrc[x]; // Store this byte.
  811. if (i == 4) // We have a full DWORD of data, write it to the chip.
  812. {
  813. REQUIRE(1);
  814. LL32 (grHOSTDATA[0], hostdata);
  815. i=0;
  816. hostdata=0;
  817. }
  818. ++x;
  819. }
  820. }
  821. // Write the last partial DWORD.
  822. if (i != 0)
  823. REQUIRE(1);
  824. LL32 (grHOSTDATA[0], hostdata);
  825. #endif
  826. // Move down one scanline in source.
  827. psrc += psoSrc->lDelta;
  828. }
  829. return TRUE;
  830. }
  831. // ************************************************************************* //
  832. // //
  833. // Color8HostToScreen() //
  834. // //
  835. // Handles 8 bpp Host to screen blts. //
  836. // //
  837. // Called by op1BLT() and op1op2BLT //
  838. // op1BLT() calls this routine with pbo = NULL. //
  839. // op1op2BLT calls it with pbo = current brush. //
  840. // //
  841. // This is the top level function. This function verifies parameters, //
  842. // and decides if we should punt or not. //
  843. // //
  844. // The BLT is then handed off to the clipping function. The clipping //
  845. // function is also given a pointer to the lower level BLT function //
  846. // HW8HostToScreen(), which will complete the clipped BLT. //
  847. // //
  848. // This function is the last chance to decide to punt. The clipping //
  849. // functions and the lower level HW8HostToScreen() function aren't //
  850. // allowed to punt. //
  851. // //
  852. // Return TRUE if we can do the BLT, //
  853. // Return FALSE to punt it back to GDI. //
  854. // //
  855. // //
  856. // ************************************************************************* //
  857. BOOL Color8HostToScreen(
  858. PPDEV ppdev,
  859. RECTL* prclDest,
  860. SURFOBJ* psoSrc,
  861. POINTL* pptlSrc,
  862. BRUSHOBJ* pbo,
  863. POINTL* pptlBrush,
  864. ULONG fg_rop,
  865. XLATEOBJ* pxlo,
  866. CLIPOBJ* pco)
  867. {
  868. ULONG bltdef = 0x1120; // RES=fb, OP0=fb OP1=host
  869. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: Color8HostToScreen Entry.\n"));
  870. //
  871. // We don't handle src with a different color depth than the screen
  872. //
  873. if (psoSrc->iBitmapFormat != ppdev->iBitmapFormat)
  874. {
  875. PUNTCODE(13);
  876. return FALSE;
  877. }
  878. //
  879. // Translation type must be nothing or trivial.
  880. // We don't handle Xlates for color source.
  881. //
  882. if (!((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)))
  883. {
  884. PUNTCODE(5);
  885. return FALSE;
  886. }
  887. //
  888. // Make sure source is a standard top-down bitmap.
  889. //
  890. if ( (psoSrc->iType != STYPE_BITMAP) ||
  891. (!(psoSrc->fjBitmap & BMF_TOPDOWN)) )
  892. {
  893. PUNTCODE(4);
  894. return FALSE;
  895. }
  896. //
  897. // Set up the brush if there is one.
  898. //
  899. if (pbo)
  900. {
  901. if (SetBrush(ppdev, &bltdef, pbo, pptlBrush) == FALSE)
  902. {
  903. PUNTCODE(8);
  904. return FALSE;
  905. }
  906. }
  907. //
  908. // Function and ROP code.
  909. //
  910. REQUIRE(1);
  911. LL_DRAWBLTDEF((bltdef << 16) | fg_rop, 2);
  912. //
  913. // Turn swizzle off.
  914. //
  915. ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
  916. LL16(grCONTROL, ppdev->grCONTROL);
  917. //
  918. // Clip the BLT.
  919. // The clipping function will call HW8HostToScreen() to finish the BLT.
  920. //
  921. if ((pco == 0) || (pco->iDComplexity==DC_TRIVIAL))
  922. HW8HostToScreen(ppdev, prclDest, psoSrc, pptlSrc,
  923. pbo, pptlBrush, fg_rop, pxlo, pco);
  924. else
  925. BltClip(ppdev, pco, prclDest, psoSrc, pptlSrc,
  926. pbo, pptlBrush, fg_rop, pxlo, &HW8HostToScreen);
  927. return (TRUE);
  928. }
  929. // *************************************************************************
  930. //
  931. // HW8HostToScreen()
  932. //
  933. // This function is responsible for actually talking to the chip.
  934. // At this point we are required to handle the BLT, so we must return TRUE.
  935. // All decisions as to whether to punt or not must be made in the top level
  936. // function Color8HostToScreen().
  937. //
  938. // This function is called from BltClip() through a pointer set by
  939. // Color8HostToScreen().
  940. //
  941. /*
  942. This routine does host to screen BLTs using DWORD aligned
  943. reads on the host whenever possible.
  944. The general plan is to split the BLT into up to three stripes.
  945. The first stripe is used if the BLT doesn't begin on a DWORD
  946. boundry.
  947. This stripe is < 1 DWORD wide and uses CHAR accesses on
  948. the host, and a single DWORD write to the screen, with the
  949. source phase set to indicated which bytes are valid.
  950. The second stripe is a middle stripe that both starts and ends
  951. on DWORD boundries. This stripe will make up the bulk of large BLTs,
  952. but for narrow BLTs, it may not be used at all.
  953. The third stripe is used if the BLT doesn't end on a DWORD boundry.
  954. It is implimented much the way the first stripe is.
  955. One thing to consider is the scan line length of the bitmap on
  956. the host. We can ignore bitmaps with an odd scan line length
  957. since Windows requires that all bitmaps have an even scan line
  958. length. That leaves two interesting cases:
  959. 1) Bitmaps with a scan line length that is DWORD divisable.
  960. (even WORD length)
  961. 2) Bitmaps with a scan line lenght that is *not* DWORD divisable.
  962. (odd WORD length)
  963. For case one, the above plan works nicely. It handles the host data
  964. one byte at a time until it reaches the first DWORD boundry, then
  965. it handles the data one DWORD at a time, until there is less than
  966. one DWORD of data left, and then handles the last couple of bytes
  967. one byte at a time.
  968. For case two, however, the plan only works for odd scan lines.
  969. When BLTing the large "aligned" block in the middle of the BLT,
  970. the odd scan lines will all align nicely on DWORD boundries,
  971. but the even scan lines will be "off" by one word. While this
  972. is not optimal, it "almost" optimal, and is easier than an
  973. optimal solution, and will work even on a Power PC.
  974. The code looks something like this:
  975. if (BLT is 4 bytes wide or less)
  976. {
  977. Read host one byte at a time, pack it into DWORDS, and
  978. write it to the chip.
  979. }
  980. else
  981. {
  982. if (left edge of the source doesn't align to a DWORD address)
  983. {
  984. Split the BLT at the first DWORD boundry on the source.
  985. BLT the left part like it was an under-4-byte-wide BLT.
  986. (see above)
  987. Adjust BLT source, destination and extents to exclude
  988. the stripe just done.
  989. }
  990. //
  991. // Now we know that the left edge of source aligns to a
  992. // DWORD boundry on the host.
  993. //
  994. if (right edge of source doesn't align to a DWORD address)
  995. {
  996. Split off a stripe to the right of the last DWORD
  997. boundry, and use an under-4-byte-wide BLT on it.
  998. Adjust BLT extent to exclude the stripe just done.
  999. }
  1000. //
  1001. // Anything left over will always DWORD aligned on both edges.
  1002. //
  1003. if (there is any part of the BLT left over)
  1004. {
  1005. do an ALINGED BLT.
  1006. }
  1007. }
  1008. All Done!
  1009. */
  1010. //
  1011. // *************************************************************************
  1012. BOOL HW8HostToScreen(
  1013. PPDEV ppdev,
  1014. RECTL* prclDest,
  1015. SURFOBJ* psoSrc,
  1016. POINTL* pptlSrc,
  1017. BRUSHOBJ* pbo,
  1018. POINTL* pptlBrush,
  1019. ULONG fg_rop,
  1020. XLATEOBJ* pxlo,
  1021. CLIPOBJ* pco)
  1022. {
  1023. PBYTE psrc;
  1024. DWORD *pdsrc;
  1025. UCHAR *pucData;
  1026. ULONG temp, x, y,
  1027. ulExtX, ulExtY,
  1028. ulDstX, ulDstY;
  1029. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: HW8HostToScreen Entry.\n"));
  1030. //
  1031. // Calculate BLT size in pixels.
  1032. //
  1033. ulDstX = prclDest->left;
  1034. ulDstY = prclDest->top;
  1035. ulExtX = (prclDest->right - prclDest->left);
  1036. ulExtY = (prclDest->bottom - prclDest->top);
  1037. //
  1038. // Get the address of the upper left source pixel.
  1039. //
  1040. pucData = psoSrc->pvScan0; // Start of surface.
  1041. pucData += (psoSrc->lDelta * pptlSrc->y); // Start of scanline.
  1042. pucData += (pptlSrc->x * ppdev->iBytesPerPixel); // Starting pixel.
  1043. //
  1044. // if the BLT is 4 or less bytes wide, just do it.
  1045. //
  1046. if (ulExtX <= 4)
  1047. {
  1048. // Do the BLT and exit.
  1049. DoNarrowH2SBlt( ppdev,
  1050. ulDstX, ulDstY,
  1051. ulExtX, ulExtY,
  1052. pucData, psoSrc->lDelta);
  1053. return TRUE;
  1054. }
  1055. //
  1056. // Is the left edge DWORD aligned?
  1057. //
  1058. temp = ((ULONG)pucData) % 4;
  1059. if ( temp != 0) // No.
  1060. {
  1061. ULONG ulLeftStripeExtX;
  1062. //
  1063. // Blt the unaligned left edge.
  1064. //
  1065. ulLeftStripeExtX = (4 - temp);
  1066. DoNarrowH2SBlt( ppdev,
  1067. ulDstX, ulDstY,
  1068. ulLeftStripeExtX, ulExtY,
  1069. pucData, psoSrc->lDelta);
  1070. //
  1071. // Adjust BLT parameters to exclude the part we just did.
  1072. //
  1073. ulDstX = ulDstX + ulLeftStripeExtX;
  1074. ulExtX = ulExtX - ulLeftStripeExtX;
  1075. pucData = pucData + ulLeftStripeExtX;
  1076. }
  1077. //
  1078. // Is the right edge DWORD aligned?
  1079. //
  1080. temp = ((ULONG)(pucData + ulExtX)) % 4;
  1081. if (temp != 0) // No.
  1082. {
  1083. ULONG ulMiddleStripeExtX,
  1084. ulRightStripeExtX,
  1085. ulRightStripeDstX;
  1086. UCHAR * pucRightStripeData;
  1087. //
  1088. // Break the BLT into a middle (aligned) stripe and a
  1089. // right (unaligned) stripe.
  1090. // The middle stripe could be 0 width.
  1091. //
  1092. ulRightStripeExtX = temp;
  1093. ulMiddleStripeExtX = ulExtX - ulRightStripeExtX;
  1094. ulRightStripeDstX = ulDstX + ulMiddleStripeExtX;
  1095. pucRightStripeData = pucData + ulMiddleStripeExtX;
  1096. //
  1097. // BLT the right (unaligned) stripe.
  1098. //
  1099. DoNarrowH2SBlt( ppdev,
  1100. ulRightStripeDstX, ulDstY,
  1101. ulRightStripeExtX, ulExtY,
  1102. pucRightStripeData, psoSrc->lDelta);
  1103. //
  1104. // Adjust BLT parameters to exclude the right stripe we just did.
  1105. //
  1106. ulExtX = ulMiddleStripeExtX;
  1107. }
  1108. //
  1109. // If anything remains, it is aligned to a DWORD boundry
  1110. // on the HOST and is an multiple of 4 wide.
  1111. //
  1112. if (ulExtX != 0)
  1113. {
  1114. DoAlignedH2SBlt
  1115. (ppdev, ulDstX, ulDstY, ulExtX, ulExtY, pucData, psoSrc->lDelta);
  1116. }
  1117. return TRUE;
  1118. }
  1119. //****************************************************************************
  1120. //
  1121. // DoNarrowBlt() -- Does an 8bpp BLT that is no more than 4 pixels wide
  1122. //
  1123. //****************************************************************************
  1124. VOID DoNarrowH2SBlt(
  1125. PPDEV ppdev,
  1126. ULONG ulDstX,
  1127. ULONG ulDstY,
  1128. ULONG ulExtX,
  1129. ULONG ulExtY,
  1130. UCHAR *pucImageD,
  1131. ULONG deltaX)
  1132. {
  1133. ULONG usDataIncrement = deltaX,
  1134. usSrcPhase = 0,
  1135. ulY;
  1136. UCHAR *pucData = pucImageD;
  1137. union
  1138. {
  1139. ULONG ul;
  1140. struct
  1141. {
  1142. unsigned char c0;
  1143. unsigned char c1;
  1144. unsigned char c2;
  1145. unsigned char c3;
  1146. } b;
  1147. } hostdata;
  1148. DISPDBG(( (H2S_DBG_LEVEL), "DrvBitBlt: Entry to DoNarrowH2SBlt.\n"));
  1149. REQUIRE(7);
  1150. LL_OP1(usSrcPhase,0);
  1151. LL_OP0 (ulDstX, ulDstY);
  1152. LL_BLTEXT (ulExtX, ulExtY);
  1153. //
  1154. // Since there are only 4 possible x extents,
  1155. // we will handle each seperatly for maximum speed.
  1156. //
  1157. switch (ulExtX)
  1158. {
  1159. case 1:
  1160. for (ulY = 0; ulY < ulExtY; ulY++)
  1161. {
  1162. #if USE_DWORD_CAST // Intel x86 can do DWORD access anywhere.
  1163. REQUIRE(1);
  1164. LL32 (grHOSTDATA[0], ((ULONG)pucData[0]) );
  1165. #else
  1166. hostdata.ul = 0;
  1167. hostdata.b.c0 = pucData[0];
  1168. REQUIRE(1);
  1169. LL32 (grHOSTDATA[0], hostdata.ul );
  1170. #endif
  1171. pucData += usDataIncrement; // Move to next scan line.
  1172. } // End for each scan line.
  1173. break;
  1174. case 2:
  1175. for (ulY = 0; ulY < ulExtY; ulY++)
  1176. {
  1177. #if USE_DWORD_CAST // Intel x86 can do DWORD access anywhere.
  1178. REQUIRE(1);
  1179. LL32 (grHOSTDATA[0], (ULONG)(*((unsigned short *) pucData)) );
  1180. #else
  1181. hostdata.ul = 0;
  1182. hostdata.b.c1 = pucData[1];
  1183. hostdata.b.c0 = pucData[0];
  1184. REQUIRE(1);
  1185. LL32 (grHOSTDATA[0], hostdata.ul );
  1186. #endif
  1187. pucData += usDataIncrement; // Move to next scan line.
  1188. } // End for each scan line.
  1189. break;
  1190. case 3:
  1191. for (ulY = 0; ulY < ulExtY; ulY++)
  1192. {
  1193. hostdata.ul = 0;
  1194. hostdata.b.c2 = pucData[2];
  1195. hostdata.b.c1 = pucData[1];
  1196. hostdata.b.c0 = pucData[0];
  1197. REQUIRE(1);
  1198. LL32 (grHOSTDATA[0], hostdata.ul );
  1199. pucData += usDataIncrement; // Move to next scan line.
  1200. } // End for each scan line.
  1201. break;
  1202. case 4:
  1203. for (ulY = 0; ulY < ulExtY; ulY++)
  1204. {
  1205. #if USE_DWORD_CAST // Intel x86 can do DWORD access anywhere.
  1206. REQUIRE(1);
  1207. LL32 (grHOSTDATA[0], (*((unsigned long *) pucData)) );
  1208. #else
  1209. hostdata.b.c3 = pucData[3];
  1210. hostdata.b.c2 = pucData[2];
  1211. hostdata.b.c1 = pucData[1];
  1212. hostdata.b.c0 = pucData[0];
  1213. REQUIRE(1);
  1214. LL32 (grHOSTDATA[0], hostdata.ul );
  1215. #endif
  1216. pucData += usDataIncrement; // Move to next scan line.
  1217. } // End for each scan line.
  1218. break;
  1219. } // End switch.
  1220. }
  1221. //****************************************************************************
  1222. //
  1223. // DoAlignedH2SBlt()
  1224. //
  1225. // Does an aligned 8bpp BLT.
  1226. // On entry Source will always be aligned to a DWORD boundry and
  1227. // X extent will always be a DWORD multiple.
  1228. //
  1229. //****************************************************************************
  1230. VOID DoAlignedH2SBlt(
  1231. PPDEV ppdev,
  1232. ULONG ulDstX,
  1233. ULONG ulDstY,
  1234. ULONG ulExtX,
  1235. ULONG ulExtY,
  1236. UCHAR *pucData,
  1237. ULONG deltaX)
  1238. {
  1239. ULONG ulX, ulY, i, num_extra, ulNumDwords,
  1240. usDataIncrement, usSrcPhase;
  1241. void *pdst = (void *)ppdev->pLgREGS->grHOSTDATA;
  1242. DISPDBG(( (H2S_DBG_LEVEL), "DrvBitBlt: Entry to DoAlignedH2SBlt.\n"));
  1243. ulNumDwords = ulExtX / 4;
  1244. usDataIncrement = deltaX;
  1245. usSrcPhase = 0;
  1246. //
  1247. // We have a bug in the chip that causes it to require extra data under
  1248. // certian conditions. We use a look-up table to see how much extra
  1249. // data this BLT will require for each scanline.
  1250. //
  1251. i = MAKE_HD_INDEX(ulExtX, usSrcPhase, ulDstX);
  1252. num_extra = ExtraDwordTable [i];
  1253. //
  1254. // Set up the chip.
  1255. //
  1256. REQUIRE(7);
  1257. LL_OP1 (usSrcPhase,0);
  1258. LL_OP0 (ulDstX, ulDstY);
  1259. LL_BLTEXT (ulExtX, ulExtY);
  1260. //
  1261. // Supply the HOSTDATA.
  1262. // We keep the decision about whether we have to work
  1263. // around the HOSTDATA bug *outside* of the loop, even though
  1264. // that means keeping two copies of it.
  1265. //
  1266. if (num_extra) // Do we have to deal with the HostData bug?
  1267. {
  1268. //
  1269. // Yes, append extra DWORDs to the end of each scan line.
  1270. //
  1271. for (ulY = 0; ulY < ulExtY; ulY++) // for each scan line.
  1272. {
  1273. // Write the data for this scan line.
  1274. WRITE_STRING(pucData, ulNumDwords);
  1275. // Write extra data to get around chip bug.
  1276. REQUIRE(num_extra);
  1277. for (i=0; i<num_extra; ++i)
  1278. LL32 (grHOSTDATA[0], 0);
  1279. // Move to next scan line.
  1280. pucData += usDataIncrement;
  1281. } // End for each scan line.
  1282. }
  1283. else
  1284. {
  1285. //
  1286. // No need to worry about the HOSTDATA bug,
  1287. // Just blast the data out there.
  1288. //
  1289. for (ulY = 0; ulY < ulExtY; ulY++) // for each scan line.
  1290. {
  1291. // Write the data for this scan line.
  1292. WRITE_STRING(pucData, ulNumDwords);
  1293. // Move to next scan line.
  1294. pucData += usDataIncrement;
  1295. } // End for each scan line.
  1296. }
  1297. }
  1298. // ===========================================================================
  1299. //
  1300. // Color16HostToScreen
  1301. //
  1302. // Handles 16 bpp Host to screen blts.
  1303. //
  1304. // Called by op1BLT() and op1op2BLT
  1305. // op1BLT() calls this routine with pbo = NULL.
  1306. // op1op2BLT calls it with pbo = current brush.
  1307. //
  1308. // This is the top level function. This function verifies parameters,
  1309. // and decides if we should punt or not.
  1310. //
  1311. // The BLT is then handed off to the clipping function. The clipping
  1312. // function is also given a pointer to the lower level BLT function
  1313. // HW16HostToScreen(), which will complete the clipped BLT.
  1314. //
  1315. // This function is the last chance to decide to punt. The clipping
  1316. // functions and the lower level HW16HostToScreen() function aren't
  1317. // allowed to punt.
  1318. //
  1319. // Return TRUE if we can do the BLT,
  1320. // Return FALSE to punt it back to GDI.
  1321. //
  1322. // ===========================================================================
  1323. BOOL Color16HostToScreen(
  1324. PPDEV ppdev,
  1325. RECTL* prclDest,
  1326. SURFOBJ* psoSrc,
  1327. POINTL* pptlSrc,
  1328. BRUSHOBJ* pbo,
  1329. POINTL* pptlBrush,
  1330. ULONG fg_rop,
  1331. XLATEOBJ* pxlo,
  1332. CLIPOBJ* pco)
  1333. {
  1334. PULONG pulXlate;
  1335. ULONG bltdef = 0x1120; // RES=fb, OP0=fb OP1=host
  1336. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: Color16HostToScreen Entry.\n"));
  1337. //
  1338. // We don't handle src with a different color depth than the screen
  1339. //
  1340. if (psoSrc->iBitmapFormat != ppdev->iBitmapFormat)
  1341. {
  1342. PUNTCODE(13);
  1343. return FALSE;
  1344. }
  1345. //
  1346. // Get the source translation type.
  1347. // We don't handle Xlates for color source.
  1348. //
  1349. if (!((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)))
  1350. {
  1351. PUNTCODE(5);
  1352. return FALSE;
  1353. }
  1354. //
  1355. // Make sure source is a standard top-down bitmap.
  1356. //
  1357. if ( (psoSrc->iType != STYPE_BITMAP) ||
  1358. (!(psoSrc->fjBitmap & BMF_TOPDOWN)) )
  1359. {
  1360. PUNTCODE(4);
  1361. return FALSE;
  1362. }
  1363. //
  1364. // Set up the brush if there is one.
  1365. //
  1366. if (pbo)
  1367. if (SetBrush(ppdev, &bltdef, pbo, pptlBrush) == FALSE)
  1368. {
  1369. PUNTCODE(8);
  1370. return FALSE;
  1371. }
  1372. //
  1373. // Turn swizzle off.
  1374. //
  1375. ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
  1376. LL16(grCONTROL, ppdev->grCONTROL);
  1377. //
  1378. // BLTDEF, and rop code.
  1379. //
  1380. REQUIRE(1);
  1381. LL_DRAWBLTDEF((bltdef << 16) | fg_rop, 2);
  1382. //
  1383. // Clip the BLT.
  1384. // The clipping function will call HW16HostToScreen() to finish the BLT.
  1385. //
  1386. if ((pco == 0) || (pco->iDComplexity==DC_TRIVIAL))
  1387. HW16HostToScreen(ppdev, prclDest, psoSrc, pptlSrc,
  1388. pbo, pptlBrush, fg_rop, pxlo, pco);
  1389. else
  1390. BltClip(ppdev, pco, prclDest, psoSrc, pptlSrc,
  1391. pbo, pptlBrush, fg_rop, pxlo, &HW16HostToScreen);
  1392. return TRUE;
  1393. }
  1394. // ===========================================================================
  1395. //
  1396. // HW16HostToScreen
  1397. //
  1398. // This function is responsible for actually talking to the chip.
  1399. // At this point we are required to handle the BLT, so we must return TRUE.
  1400. // All decisions as to whether to punt or not must be made in the top level
  1401. // function Color16HostToScreen().
  1402. //
  1403. // This function is called from BltClip() through a pointer set by
  1404. // Color16HostToScreen(). //
  1405. //
  1406. // Since scan lines are WORD aligned by GDI, that means
  1407. // all pixels will be WORD aligned by GDI, so the only thing
  1408. // we need to be concerned about is if there are a even or an odd
  1409. // number of WORDS per scan line.
  1410. //
  1411. // ===========================================================================
  1412. BOOL HW16HostToScreen(
  1413. PPDEV ppdev,
  1414. RECTL* prclDest,
  1415. SURFOBJ* psoSrc,
  1416. POINTL* pptlSrc,
  1417. BRUSHOBJ* pbo,
  1418. POINTL* pptlBrush,
  1419. ULONG fg_rop,
  1420. XLATEOBJ* pxlo,
  1421. CLIPOBJ* pco)
  1422. {
  1423. ULONG bltWidth, bltHeight,
  1424. x, y, i, odd,
  1425. num_dwords, num_extra;
  1426. PBYTE psrc;
  1427. DWORD *pdsrc;
  1428. UCHAR *pucData;
  1429. ULONG SrcPhase = 0;
  1430. void *pHOSTDATA = (void *)ppdev->pLgREGS->grHOSTDATA;
  1431. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: HW16HostToScreen Entry.\n"));
  1432. //
  1433. // Set psrc to point to first pixel in source.
  1434. //
  1435. psrc = psoSrc->pvScan0; // Start of surface.
  1436. psrc += (psoSrc->lDelta * pptlSrc->y); // Start of scanline.
  1437. psrc += (pptlSrc->x * ppdev->iBytesPerPixel); // Starting pixel in scanline.
  1438. //
  1439. // Set source phase
  1440. //
  1441. REQUIRE(7);
  1442. LL_OP1 (SrcPhase,0);
  1443. //
  1444. // Set DEST x,y
  1445. //
  1446. LL_OP0 (prclDest->left, prclDest->top);
  1447. //
  1448. // Set the X and Y extents, and do the BLT.
  1449. // Calculate BLT size in pixels.
  1450. //
  1451. bltWidth = (prclDest->right - prclDest->left);
  1452. bltHeight = (prclDest->bottom - prclDest->top);
  1453. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: BLT width is %d pixels.\n",bltWidth));
  1454. LL_BLTEXT (bltWidth, bltHeight);
  1455. //
  1456. // The chip has a bug in it that causes us to have to write extra HOSTDATA
  1457. // under certian conditions.
  1458. //
  1459. i = MAKE_HD_INDEX((bltWidth*2), SrcPhase, (prclDest->left*2));
  1460. num_extra = ExtraDwordTable [i];
  1461. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: BLT requires %d extra HOSTDATA writes.\n",num_extra));
  1462. //
  1463. // Now we supply the HOSTDATA for each scan line.
  1464. //
  1465. for (y=0; y<bltHeight; ++y)
  1466. {
  1467. WRITE_STRING(psrc, ((bltWidth + 1) / 2);
  1468. //
  1469. // Add any extra hostdata we need to get around the hostdata bug.
  1470. //
  1471. REQUIRE(num_extra);
  1472. for (i=0; i<num_extra; ++i)
  1473. LL32 (grHOSTDATA[0], 0);
  1474. // Move down one scanline in source.
  1475. psrc += psoSrc->lDelta;
  1476. }
  1477. return TRUE;
  1478. }
  1479. // ===========================================================================
  1480. //
  1481. // Color24HostToScreen
  1482. //
  1483. // Handles 24 bpp Host to screen blts.
  1484. //
  1485. // Called by op1BLT() and op1op2BLT
  1486. // op1BLT() calls this routine with pbo = NULL.
  1487. // op1op2BLT calls it with pbo = current brush.
  1488. //
  1489. // This is the top level function. This function verifies parameters,
  1490. // and decides if we should punt or not.
  1491. //
  1492. // The BLT is then handed off to the clipping function. The clipping
  1493. // function is also given a pointer to the lower level BLT function
  1494. // HW24HostToScreen(), which will complete the clipped BLT.
  1495. //
  1496. // This function is the last chance to decide to punt. The clipping
  1497. // functions and the lower level HW24HostToScreen() function aren't
  1498. // allowed to punt.
  1499. //
  1500. // Return TRUE if we can do the BLT,
  1501. // Return FALSE to punt it back to GDI.
  1502. //
  1503. // ===========================================================================
  1504. BOOL Color24HostToScreen(
  1505. PPDEV ppdev,
  1506. RECTL* prclDest,
  1507. SURFOBJ* psoSrc,
  1508. POINTL* pptlSrc,
  1509. BRUSHOBJ* pbo,
  1510. POINTL* pptlBrush,
  1511. ULONG fg_rop,
  1512. XLATEOBJ* pxlo,
  1513. CLIPOBJ* pco)
  1514. {
  1515. //
  1516. // I'm not even going to try this.
  1517. // I've got better things to do with my time.
  1518. //
  1519. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: Color24HostToScreen Entry.\n"));
  1520. PUNTCODE(17);
  1521. return FALSE;
  1522. }
  1523. // ===========================================================================
  1524. //
  1525. // Color32HostToScreen
  1526. //
  1527. // Handles 32 bpp Host to screen blts.
  1528. //
  1529. // Called by op1BLT() and op1op2BLT
  1530. // op1BLT() calls this routine with pbo = NULL.
  1531. // op1op2BLT calls it with pbo = current brush.
  1532. //
  1533. // This is the top level function. This function verifies parameters,
  1534. // and decides if we should punt or not.
  1535. //
  1536. // The BLT is then handed off to the clipping function. The clipping
  1537. // function is also given a pointer to the lower level BLT function
  1538. // HW24HostToScreen(), which will complete the clipped BLT.
  1539. //
  1540. // This function is the last chance to decide to punt. The clipping
  1541. // functions and the lower level HW24HostToScreen() function aren't
  1542. // allowed to punt.
  1543. //
  1544. // Return TRUE if we can do the BLT,
  1545. // Return FALSE to punt it back to GDI.
  1546. //
  1547. // ===========================================================================
  1548. BOOL Color32HostToScreen(
  1549. PPDEV ppdev,
  1550. RECTL* prclDest,
  1551. SURFOBJ* psoSrc,
  1552. POINTL* pptlSrc,
  1553. BRUSHOBJ* pbo,
  1554. POINTL* pptlBrush,
  1555. ULONG fg_rop,
  1556. XLATEOBJ* pxlo,
  1557. CLIPOBJ* pco)
  1558. {
  1559. PULONG pulXlate;
  1560. ULONG bltdef = 0x1120; // RES=fb, OP0=fb OP1=host
  1561. return FALSE; // There are some unresolved issues here.
  1562. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: Color32HostToScreen Entry.\n"));
  1563. //
  1564. // We don't handle src with a different color depth than the screen
  1565. //
  1566. if (psoSrc->iBitmapFormat != ppdev->iBitmapFormat)
  1567. {
  1568. PUNTCODE(13); return FALSE;
  1569. }
  1570. //
  1571. // Get the source translation type.
  1572. // We don't handle Xlates for color source.
  1573. //
  1574. if (!((pxlo == NULL) || (pxlo->flXlate & XO_TRIVIAL)))
  1575. {
  1576. PUNTCODE(5); return FALSE;
  1577. }
  1578. //
  1579. // Make sure source is a standard top-down bitmap.
  1580. //
  1581. if ( (psoSrc->iType != STYPE_BITMAP) ||
  1582. (!(psoSrc->fjBitmap & BMF_TOPDOWN)) )
  1583. {
  1584. PUNTCODE(4); return FALSE;
  1585. }
  1586. //
  1587. // Set up the brush if there is one.
  1588. //
  1589. if (pbo)
  1590. if (SetBrush(ppdev, &bltdef, pbo, pptlBrush) == FALSE)
  1591. {
  1592. PUNTCODE(8);
  1593. return FALSE;
  1594. }
  1595. //
  1596. // Source phase.
  1597. //
  1598. //LL16 (grOP1_opRDRAM.pt.X, (WORD)0);
  1599. REQUIRE(4);
  1600. LL_OP1(0,0);
  1601. //
  1602. // Turn swizzle off.
  1603. //
  1604. ppdev->grCONTROL = ppdev->grCONTROL & ~SWIZ_CNTL;
  1605. LL16(grCONTROL, ppdev->grCONTROL);
  1606. //
  1607. // BLTDEF, and rop code.
  1608. //
  1609. LL_DRAWBLTDEF((bltdef << 16) | fg_rop, 2);
  1610. //
  1611. // Clip the BLT.
  1612. // The clipping function will call HW16HostToScreen() to finish the BLT.
  1613. //
  1614. if ((pco == 0) || (pco->iDComplexity==DC_TRIVIAL))
  1615. HW32HostToScreen(ppdev, prclDest, psoSrc, pptlSrc,
  1616. pbo, pptlBrush, fg_rop, pxlo, pco);
  1617. else
  1618. BltClip(ppdev, pco, prclDest, psoSrc, pptlSrc,
  1619. pbo, pptlBrush, fg_rop, pxlo, &HW32HostToScreen);
  1620. return TRUE;
  1621. } // ===========================================================================
  1622. //
  1623. // HW32HostToScreen
  1624. //
  1625. // This function is responsible for actually talking to the chip.
  1626. // At this point we are required to handle the BLT, so we must return TRUE.
  1627. // All decisions as to whether to punt or not must be made in the top level
  1628. // function Color32HostToScreen().
  1629. //
  1630. // This function is called from BltClip() through a pointer set by
  1631. // Color326HostToScreen().
  1632. //
  1633. // ===========================================================================
  1634. BOOL HW32HostToScreen(
  1635. PPDEV ppdev,
  1636. RECTL* prclDest,
  1637. SURFOBJ* psoSrc,
  1638. POINTL* pptlSrc,
  1639. BRUSHOBJ* pbo,
  1640. POINTL* pptlBrush,
  1641. ULONG fg_rop,
  1642. XLATEOBJ* pxlo,
  1643. CLIPOBJ* pco)
  1644. {
  1645. ULONG x, y, i,
  1646. bltWidth, bltHeight,
  1647. num_dwords, num_extra;
  1648. PBYTE psrc;
  1649. DWORD *pdsrc;
  1650. UCHAR *pucData;
  1651. ULONG SrcPhase = 0;
  1652. void *pHOSTDATA = (void *)ppdev->pLgREGS->grHOSTDATA;
  1653. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: HW32HostToScreen Entry.\n"));
  1654. //
  1655. // Set psrc to point to first pixel in source.
  1656. //
  1657. psrc = psoSrc->pvScan0; // Start of surface.
  1658. psrc += (psoSrc->lDelta * pptlSrc->y); // Start of scanline.
  1659. psrc += (pptlSrc->x * ppdev->iBytesPerPixel); // Starting pixel in scanline.
  1660. //
  1661. // Set DEST x,y
  1662. //
  1663. REQUIRE(5);
  1664. LL_OP0 (prclDest->left, prclDest->top);
  1665. //
  1666. // Set the X and Y extents, and do the BLT.
  1667. // Calculate BLT size in pixels.
  1668. //
  1669. bltWidth = (prclDest->right - prclDest->left);
  1670. bltHeight = (prclDest->bottom - prclDest->top);
  1671. LL_BLTEXT (bltWidth, bltHeight);
  1672. //
  1673. // Now we supply the HOSTDATA.
  1674. // 1 pixel per DWORD. This is easy.
  1675. //
  1676. //
  1677. // The chip has a bug in it that causes us to have to write extra HOSTDATA
  1678. // under certian conditions.
  1679. //
  1680. i = MAKE_HD_INDEX((bltWidth*4), SrcPhase, (prclDest->left*4));
  1681. num_extra = ExtraDwordTable [i];
  1682. DISPDBG(( H2S_DBG_LEVEL, "DrvBitBlt: BLT requires %d extra HOSTDATA writes.\n",num_extra));
  1683. // Supply HOSTDATA for each scan line.
  1684. for (y=0; y<bltHeight; ++y)
  1685. {
  1686. WRITE_STRING(psrc, bltWidth);
  1687. //
  1688. // Add any extra hostdata we need to get around the hostdata bug.
  1689. //
  1690. REQUIRE(num_extra);
  1691. for (i=0; i<num_extra; ++i)
  1692. LL32 (grHOSTDATA[0], 0);
  1693. // Move down one scanline in source.
  1694. psrc += psoSrc->lDelta;
  1695. }
  1696. return TRUE;
  1697. }
  1698. #endif // 0
  1699. #endif // BUS_MASTER