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.

722 lines
22 KiB

  1. /*******************************Module*Header*****************************\
  2. *
  3. * Copyright (c) 1992-1999 Microsoft Corporation
  4. * Copyright (c) 1992 Digital Equipment Corporation
  5. *
  6. * Module Name:
  7. *
  8. * tiler.cxx
  9. *
  10. * Abstract:
  11. *
  12. * This module implements code to copy a pattern to a target surface.
  13. *
  14. * Author:
  15. *
  16. * David N. Cutler (davec) 4-May-1992
  17. *
  18. * Rewritten in C by:
  19. *
  20. * Eric Rehm (rehm@zso.dec.com) 15-July-1992
  21. *
  22. * Environment:
  23. *
  24. * Kernel mode only.
  25. *
  26. * N.B. The AMD64 platform does not enforce alignment checks in kernel
  27. * mode. Therefore, even though this function deals with data that
  28. * is unaligned, avoidance of unaligned operations is not required.
  29. *
  30. * Revision History:
  31. *
  32. \*************************************************************************/
  33. #include "precomp.hxx"
  34. VOID CopyPattern( PULONG pulTrg, LONG culFill, LONG hiPat, LONG loPat);
  35. VOID MergePattern( PULONG pulTrg, LONG culFill, LONG hiPat, LONG loPat);
  36. /****************************Public*Routine******************************\
  37. *
  38. * extern "C" VOID
  39. * vFetchAndCopy (
  40. * IN PFETCHFRAME pff
  41. * )
  42. *
  43. * Routine Description:
  44. *
  45. * This routine repeatedly tiles one scan line of an aligned pattern.
  46. *
  47. * Arguments:
  48. *
  49. * pff - Supplies a pointer to a fetch frame.
  50. *
  51. * Return Value:
  52. *
  53. * None.
  54. *
  55. \*************************************************************************/
  56. extern "C" VOID vFetchAndCopy
  57. (
  58. FETCHFRAME *pff
  59. )
  60. {
  61. PULONG pulTrg; // target surface address
  62. PULONG pulTrgEnd; // ending targe surface address
  63. PULONG pulPat; // base pattern address
  64. PULONG pulPatCur; // current pattern address
  65. PULONG pulPatEnd; // ending pattern address
  66. ULONG xPat; // pattern offset
  67. ULONG cxPat; // pattern width in pixels
  68. ULONG culFill; // fill size in longwords
  69. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  70. // Make copies of some things
  71. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  72. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  73. xPat = pff->xPat; // pattern offset in bytes (t2)
  74. cxPat = pff->cxPat; // pattern width in pixels (t3)
  75. culFill = pff->culFill; // Size of fill in longwords
  76. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  77. pulPatCur = (PULONG) ((PUCHAR) pulPat + xPat);
  78. // compute current pattern address (t5)
  79. if (cxPat == 8) // check if pattern is exactly 8 pels
  80. {
  81. loPat = *pulPatCur; // get low part of 8-byte pattern
  82. if (xPat == 0)
  83. {
  84. hiPat = *(pulPatCur + 1); // get hi part of 8-byte pattern
  85. }
  86. else
  87. {
  88. hiPat = *pulPat; // get hi part of 8-byte pattern
  89. }
  90. CopyPattern( pulTrg, culFill, hiPat, loPat); // do a 4 or 8-byte copy
  91. }
  92. else
  93. {
  94. //
  95. // The pattern is not 8 bytes in width
  96. // or cannot be moved 8 bytes at a time
  97. //
  98. pulPatEnd = (PULONG) ((PUCHAR) pulPat + cxPat);
  99. // ending pattern address
  100. while (pulTrg < pulTrgEnd)
  101. {
  102. *pulTrg = *pulPatCur; // set target to 4-byte pattern value
  103. pulTrg += 1; // advance the target ptr one longword
  104. pulPatCur += 1; // advance the pattern pixel offset
  105. if (pulPatCur == pulPatEnd) // Check if at end of pattern
  106. {
  107. pulPatCur = pulPat; // get starting pattern address
  108. }
  109. }
  110. }
  111. } // end vFetchAndCopy
  112. /****************************Public*Routine******************************\
  113. *
  114. * extern "C" VOID
  115. * vFetchShiftAndCopy (
  116. * IN PFETCHFRAME pff
  117. * )
  118. *
  119. * Routine Description:
  120. *
  121. * This routine repeatedly tiles one scan line of an unaligned pattern
  122. * using rop (P).
  123. *
  124. * Arguments:
  125. *
  126. * pff - Supplies a pointer to a fetch frame.
  127. *
  128. * Return Value:
  129. *
  130. * None.
  131. *
  132. \*************************************************************************/
  133. extern "C" VOID vFetchShiftAndCopy
  134. (
  135. FETCHFRAME *pff
  136. )
  137. {
  138. PULONG pulTrg; // target surface address
  139. PULONG pulTrgEnd; // ending targe surface address
  140. ULONG *pulPat; // base pattern address
  141. ULONG *pulPatCur; // current pattern address
  142. ULONG xPat; // pattern offset
  143. ULONG cxPat; // pattern width in pixels
  144. ULONG culFill; // fill size in longwords
  145. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  146. // Make copies of some things
  147. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  148. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  149. xPat = pff->xPat; // pattern offset in bytes (t2)
  150. cxPat = pff->cxPat; // pattern width in pixels (t3)
  151. culFill = pff->culFill; // Size of fill in longwords
  152. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  153. pulPatCur = (ULONG *) ((PUCHAR) pulPat + xPat);
  154. // compute current pattern address (t5)
  155. if (cxPat == 8) // check if pattern is exactly 8 pels
  156. {
  157. loPat = *pulPatCur; // get low part of 8-byte pattern
  158. xPat +=4; // get hi part of 8-byte pattern
  159. if (xPat >= cxPat)
  160. {
  161. xPat -= cxPat;
  162. }
  163. hiPat = *((ULONG *) ((PUCHAR) pulPat + xPat));
  164. CopyPattern( pulTrg, culFill, hiPat, loPat); // do a 4 or 8-byte copy
  165. }
  166. else
  167. {
  168. //
  169. // The pattern is not 8 bytes in width
  170. // or cannot be moved 8 bytes at a time
  171. //
  172. while (pulTrg < pulTrgEnd)
  173. {
  174. *pulTrg = *pulPatCur;
  175. // set target to 4-byte pattern value
  176. pulTrg += 1; // advance the target ptr one longword
  177. xPat += 4;
  178. if (xPat >= cxPat)
  179. {
  180. xPat -= cxPat;
  181. }
  182. pulPatCur = (ULONG *) ((PUCHAR) pulPat + xPat);
  183. }
  184. }
  185. } // end vFetchShiftAndCopy
  186. /****************************Public*Routine******************************\
  187. *
  188. * extern "C" VOID
  189. * vFetchNotAndCopy (
  190. * IN PFETCHFRAME pff
  191. * )
  192. *
  193. * Routine Description:
  194. *
  195. * This routine repeatedly tiles one scan line of an aligned pattern
  196. * using rop (Pn).
  197. *
  198. * Arguments:
  199. *
  200. * pff - Supplies a pointer to a fetch frame.
  201. *
  202. * Return Value:
  203. *
  204. * None.
  205. *
  206. \*************************************************************************/
  207. extern "C" VOID vFetchNotAndCopy
  208. (
  209. FETCHFRAME *pff
  210. )
  211. {
  212. PULONG pulTrg; // target surface address
  213. PULONG pulTrgEnd; // ending targe surface address
  214. PULONG pulPat; // base pattern address
  215. PULONG pulPatCur; // current pattern address
  216. PULONG pulPatEnd; // ending pattern address
  217. ULONG xPat; // pattern offset
  218. ULONG cxPat; // pattern width in pixels
  219. ULONG culFill; // fill size in longwords
  220. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  221. // Make copies of some things
  222. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  223. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  224. xPat = pff->xPat; // pattern offset in bytes (t2)
  225. cxPat = pff->cxPat; // pattern width in pixels (t3)
  226. culFill = pff->culFill; // Size of fill in longwords
  227. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  228. pulPatCur = (PULONG) ((PUCHAR) pulPat + xPat);
  229. // compute current pattern address (t5)
  230. if (cxPat == 8) // check if pattern is exactly 8 pels
  231. {
  232. loPat = *pulPatCur; // get low part of 8-byte pattern
  233. if (xPat == 0)
  234. {
  235. hiPat = *(pulPatCur + 1); // get hi part of 8-byte pattern
  236. }
  237. else
  238. {
  239. hiPat = *pulPat; // get hi part of 8-byte pattern
  240. }
  241. loPat = ~loPat; // complement pattern
  242. hiPat = ~hiPat;
  243. CopyPattern( pulTrg, culFill, hiPat, loPat); // do a 4 or 8-byte copy
  244. }
  245. else
  246. {
  247. //
  248. // The pattern is not 8 bytes in width
  249. // or cannot be moved 8 bytes at a time
  250. //
  251. pulPatEnd = (PULONG) ((PUCHAR) pulPat + cxPat);
  252. // ending pattern address
  253. while (pulTrg < pulTrgEnd)
  254. {
  255. *pulTrg = ~(*pulPatCur);
  256. // set target to complement of 4-byte pattern value
  257. pulTrg += 1; // advance the target ptr one longword
  258. pulPatCur += 1; // advance the pattern pixel offset
  259. if (pulPatCur == pulPatEnd) // Check if at end of pattern
  260. {
  261. pulPatCur = pulPat; // get starting pattern address
  262. }
  263. }
  264. }
  265. } // end vFetchNotAndCopy
  266. /****************************Public*Routine******************************\
  267. *
  268. * extern "C" VOID
  269. * vFetchShiftNotAndCopy (
  270. * IN PFETCHFRAME pff
  271. * )
  272. *
  273. * Routine Description:
  274. *
  275. * This routine repeatedly tiles one scan line of an unaligned pattern
  276. * using rop (Pn).
  277. *
  278. * Arguments:
  279. *
  280. * pff - Supplies a pointer to a fetch frame.
  281. *
  282. * Return Value:
  283. *
  284. * None.
  285. *
  286. \*************************************************************************/
  287. extern "C" VOID vFetchShiftNotAndCopy
  288. (
  289. FETCHFRAME *pff
  290. )
  291. {
  292. PULONG pulTrg; // target surface address
  293. PULONG pulTrgEnd; // ending targe surface address
  294. ULONG *pulPat; // base pattern address
  295. ULONG *pulPatCur; // current pattern address
  296. ULONG xPat; // pattern offset
  297. ULONG cxPat; // pattern width in pixels
  298. ULONG culFill; // fill size in longwords
  299. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  300. // Make copies of some things
  301. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  302. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  303. xPat = pff->xPat; // pattern offset in bytes (t2)
  304. cxPat = pff->cxPat; // pattern width in pixels (t3)
  305. culFill = pff->culFill; // Size of fill in longwords
  306. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  307. pulPatCur = (ULONG *) ((PUCHAR) pulPat + xPat);
  308. // compute current pattern address (t5)
  309. if (cxPat == 8) // check if pattern is exactly 8 pels
  310. {
  311. loPat = *pulPatCur;
  312. // get low part of 8-byte pattern
  313. xPat +=4; // get hi part of 8-byte pattern
  314. if (xPat >= cxPat)
  315. {
  316. xPat -= cxPat;
  317. }
  318. hiPat = *((ULONG *) ((PUCHAR) pulPat + xPat));
  319. loPat = ~loPat; // complement pattern
  320. hiPat = ~hiPat;
  321. CopyPattern( pulTrg, culFill, hiPat, loPat); // do a 4 or 8-byte copy
  322. }
  323. else
  324. {
  325. //
  326. // The pattern is not 8 bytes in width
  327. // or cannot be moved 8 bytes at a time
  328. //
  329. while (pulTrg < pulTrgEnd)
  330. {
  331. *pulTrg = ~(*pulPatCur);
  332. // set target to complemented 4-byte pattern value
  333. pulTrg += 1; // advance the target ptr one longword
  334. xPat += 4;
  335. if (xPat >= cxPat)
  336. {
  337. xPat -= cxPat;
  338. }
  339. pulPatCur = (ULONG *) ((PUCHAR) pulPat + xPat);
  340. }
  341. }
  342. } // end vFetchShiftNotAndCopy
  343. /****************************Private*Routine******************************\
  344. *
  345. * VOID CopyPattern( PULONG pulTrg, LONG culFill, LONG hiPat, LONG loPat)
  346. *
  347. * Routine Description:
  348. *
  349. * This routine contains common code for copying an 8-byte pattern to
  350. * a target surface.
  351. *
  352. * Arguments:
  353. *
  354. * culFill - Supplies the size of the fill in bytes.
  355. * loPat, hiPat - Supplies the 8-byte pattern to copy.
  356. * pulTrg - Supplies the starting target surface address.
  357. *
  358. * Return Value:
  359. *
  360. * None.
  361. *
  362. *
  363. \*************************************************************************/
  364. VOID CopyPattern
  365. (
  366. PULONG pulTrg, // Starting target surface address (t0)
  367. LONG culFill, // size of fill in longwords (a1)
  368. LONG hiPat, // hi part of pattern (v1)
  369. LONG loPat // lo part of pattern (v0)
  370. )
  371. {
  372. PULONG pulTrgEnd; // ending target surface address
  373. ULONG temp; // temp for swap
  374. pulTrgEnd = pulTrg + culFill;
  375. // ending target surface address(t4)
  376. //
  377. // If the fill size is not an even multiple of 8 bytes, then move one
  378. // longword and swap the pattern value.
  379. //
  380. if ((culFill & 0x01) != 0)
  381. {
  382. *pulTrg = loPat; // store low 4 bytes of pattern
  383. pulTrg += 1; // advance target ptr one longword
  384. culFill -= 1;
  385. if (culFill == 0) // if no more to move then we're done
  386. {
  387. return;
  388. }
  389. else // otherwise, swap 8-byte pattern value
  390. {
  391. temp = loPat;
  392. loPat = hiPat;
  393. hiPat = temp;
  394. }
  395. }
  396. //
  397. // Move 8-byte pattern value to target 8 bytes at a time.
  398. //
  399. pulTrgEnd -= 2; // ending segement address
  400. if ((culFill & 0x02) != 0) // check if even multiple of 8 bytes
  401. {
  402. while (pulTrg <= pulTrgEnd) // if not, move 8 bytes at a time
  403. {
  404. *pulTrg = loPat; // store 8-byte pattern value
  405. *(pulTrg + 1) = hiPat;
  406. pulTrg += 2; // advance target address
  407. }
  408. return;
  409. }
  410. else // move 16 bytes at a time
  411. {
  412. pulTrgEnd -= 2; // ending segement address
  413. while (pulTrg <= pulTrgEnd)
  414. {
  415. *pulTrg = loPat; // store 8-byte pattern value
  416. *(pulTrg + 1) = hiPat;
  417. *(pulTrg + 2) = loPat; // store 8-byte pattern value
  418. *(pulTrg + 3) = hiPat;
  419. pulTrg += 4; // advance target address
  420. }
  421. }
  422. }
  423. /****************************Public*Routine******************************\
  424. *
  425. * extern "C" VOID
  426. * vFetchAndMerge (
  427. * IN PFETCHFRAME pff
  428. * )
  429. *
  430. * Routine Description:
  431. *
  432. * This routine repeatedly tiles one scan line of an aligned pattern
  433. * using ropt (DPx).
  434. *
  435. * Arguments:
  436. *
  437. * pff - Supplies a pointer to a fetch frame.
  438. *
  439. * Return Value:
  440. *
  441. * None.
  442. *
  443. \*************************************************************************/
  444. extern "C" VOID vFetchAndMerge
  445. (
  446. FETCHFRAME *pff
  447. )
  448. {
  449. PULONG pulTrg; // target surface address
  450. PULONG pulTrgEnd; // ending targe surface address
  451. PULONG pulPat; // base pattern address
  452. PULONG pulPatCur; // current pattern address
  453. PULONG pulPatEnd; // ending pattern address
  454. ULONG xPat; // pattern offset
  455. ULONG cxPat; // pattern width in pixels
  456. ULONG culFill; // fill size in longwords
  457. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  458. // Make copies of some things
  459. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  460. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  461. xPat = pff->xPat; // pattern offset in bytes (t2)
  462. cxPat = pff->cxPat; // pattern width in pixels (t3)
  463. culFill = pff->culFill; // Size of fill in longwords
  464. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  465. pulPatCur = (PULONG) ((PUCHAR) pulPat + xPat);
  466. // compute current pattern address (t5)
  467. if (cxPat == 8) // check if pattern is exactly 8 pels
  468. {
  469. loPat = *pulPatCur; // get low part of 8-byte pattern
  470. if (xPat == 0)
  471. {
  472. hiPat = *(pulPatCur + 1); // get hi part of 8-byte pattern
  473. }
  474. else
  475. {
  476. hiPat = *pulPat; // get hi part of 8-byte pattern
  477. }
  478. MergePattern( pulTrg, culFill, hiPat, loPat); //do a 4 or 8-byte copy
  479. }
  480. else
  481. {
  482. //
  483. // The pattern is not 8 bytes in width
  484. // or cannot be moved 8 bytes at a time
  485. //
  486. pulPatEnd = (PULONG) ((PUCHAR) pulPat + cxPat);
  487. // ending pattern address
  488. while (pulTrg < pulTrgEnd)
  489. {
  490. *pulTrg = (*pulPatCur) ^ (*pulTrg);
  491. // XOR 4-byte target with 4-byte pattern value
  492. pulTrg += 1; // advance the target ptr one longword
  493. pulPatCur += 1; // advance the pattern pixel offset
  494. if (pulPatCur == pulPatEnd) // Check if at end of pattern
  495. {
  496. pulPatCur = pulPat; // get starting pattern address
  497. }
  498. }
  499. }
  500. } // end vFetchAndMerge
  501. /****************************Public*Routine******************************\
  502. *
  503. * extern "C" VOID
  504. * vFetchShiftAndMerge (
  505. * IN PFETCHFRAME pff
  506. * )
  507. *
  508. * Routine Description:
  509. *
  510. * This routine repeatedly tiles one scan line of an unaligned pattern
  511. * using rop (P).
  512. *
  513. * Arguments:
  514. *
  515. * pff - Supplies a pointer to a fetch frame.
  516. *
  517. * Return Value:
  518. *
  519. * None.
  520. *
  521. \*************************************************************************/
  522. extern "C" VOID vFetchShiftAndMerge
  523. (
  524. FETCHFRAME *pff
  525. )
  526. {
  527. PULONG pulTrg; // target surface address
  528. PULONG pulTrgEnd; // ending targe surface address
  529. ULONG *pulPat; // base pattern address
  530. ULONG *pulPatCur; // current pattern address
  531. ULONG xPat; // pattern offset
  532. ULONG cxPat; // pattern width in pixels
  533. ULONG culFill; // fill size in longwords
  534. ULONG loPat, hiPat; // low, hi part of 8-byte pattern
  535. // Make copies of some things
  536. pulTrg = (PULONG) pff->pvTrg; // starting target surface address (t0)
  537. pulPat = (PULONG) pff->pvPat; // base pattern address (t1)
  538. xPat = pff->xPat; // pattern offset in bytes (t2)
  539. cxPat = pff->cxPat; // pattern width in pixels (t3)
  540. culFill = pff->culFill; // Size of fill in longwords
  541. pulTrgEnd = pulTrg + culFill; // compute ending target address (t4)
  542. pulPatCur = (ULONG *) ((PUCHAR) pulPat + xPat);
  543. // compute current pattern address (t5)
  544. if (cxPat == 8) // check if pattern is exactly 8 pels
  545. {
  546. loPat = *pulPatCur;
  547. // get low part of 8-byte pattern
  548. xPat +=4; // get hi part of 8-byte pattern
  549. if (xPat >= cxPat)
  550. {
  551. xPat -= cxPat;
  552. }
  553. hiPat = *((ULONG *) ((PUCHAR) pulPat + xPat));
  554. MergePattern( pulTrg, culFill, hiPat, loPat); //do a 4 or 8-byte copy
  555. }
  556. else
  557. {
  558. //
  559. // The pattern is not 8 bytes in width
  560. // or cannot be moved 8 bytes at a time
  561. //
  562. while (pulTrg < pulTrgEnd)
  563. {
  564. *pulTrg = (*pulPatCur) ^ (*pulTrg);
  565. // XOR 4-byte target with 4-byte pattern value
  566. pulTrg += 1; // advance the target ptr one longword
  567. xPat += 4;
  568. if (xPat >= cxPat)
  569. {
  570. xPat -= cxPat;
  571. }
  572. pulPatCur = (ULONG *) ((PUCHAR) pulPat + xPat);
  573. }
  574. }
  575. } // end vFetchShiftAndMerge
  576. /****************************Private*Routine******************************\
  577. *
  578. * VOID MergePattern( PULONG pulTrg, LONG culFill, LONG hiPat, LONG loPat)
  579. *
  580. * Routine Description:
  581. *
  582. * This routine contains common code for merging an 8-byte pattern with
  583. * a target surface.
  584. *
  585. * Arguments:
  586. *
  587. * culFill - Supplies the size of the fill in bytes.
  588. * loPat, hiPat - Supplies the 8-byte pattern to merge.
  589. * pulTrg - Supplies the starting target surface address.
  590. *
  591. * Return Value:
  592. *
  593. * None.
  594. *
  595. *
  596. \*************************************************************************/
  597. VOID MergePattern
  598. (
  599. PULONG pulTrg, // Starting target surface address (t0)
  600. LONG culFill, // size of fill in longwords (a1)
  601. LONG hiPat, // hi part of pattern (v1)
  602. LONG loPat // lo part of pattern (v0)
  603. )
  604. {
  605. PULONG pulTrgEnd; // ending target surface address
  606. ULONG temp; // temp for swap
  607. pulTrgEnd = pulTrg + culFill;
  608. // ending target surface address(t4)
  609. //
  610. // If the fill size is not an even multiple of 8 bytes, then move one
  611. // longword and swap the pattern value.
  612. //
  613. if ((culFill & 0x01) != 0)
  614. {
  615. *pulTrg = loPat ^ (*pulTrg); // XOR low 4 bytes of pattern w/ target
  616. pulTrg += 1; // advance target ptr one longword
  617. culFill -= 1;
  618. if (culFill == 0) // if no more to move then we're done
  619. {
  620. return;
  621. }
  622. else // otherwise, swap 8-byte pattern value
  623. {
  624. temp = loPat;
  625. loPat = hiPat;
  626. hiPat = temp;
  627. }
  628. }
  629. //
  630. // Move 8-byte pattern value to target 8 bytes at a time.
  631. //
  632. pulTrgEnd -= 2; // ending segement address
  633. while (pulTrg <= pulTrgEnd) // if not, move 8 bytes at a time
  634. {
  635. *pulTrg = loPat ^ (*pulTrg); // XOR 4-byte pattern value
  636. pulTrg++; // advance target address
  637. *pulTrg = hiPat ^ (*pulTrg); // XOR 4-byte pattern value
  638. pulTrg++; // advance target address
  639. }
  640. return;
  641. }