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.

1301 lines
44 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: draw.c
  8. *
  9. * Contains the DrvFillPath routine. Permedia P2 optimised functions
  10. *
  11. * Copyright (c) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "precomp.h"
  15. #include "gdi.h"
  16. #include "directx.h"
  17. //-----------------------------------------------------------------------------
  18. //
  19. // void vAlphaBlendDownload(GFNPB * ppb)
  20. //
  21. // Doing an alpha blend on a source surface which is in a pre-multiplied alpha
  22. // 32bpp "BGRA" format; that is, the surface type is BMF_32BPP and the palette
  23. // type is BI_RGB.
  24. //
  25. // Argumentes needed from function block (GFNPB)
  26. // ppdev-------PPDev
  27. // psoSrc------Pointer to source SURFOBJ
  28. // psurfDst----Destination surface
  29. // pRects------Pointer to a list of rectangles information which needed to be
  30. // filled
  31. // lNumRects---Number of rectangles to fill
  32. // prclDst-----Points to a RECTL structure that defines the rectangular area
  33. // to be modified
  34. // prclSrc-----Points to a RECTL structure that defines the rectangular area
  35. // to be copied
  36. // ucAlpha-----Alpha value
  37. //
  38. //-----------------------------------------------------------------------------
  39. VOID
  40. vAlphaBlendDownload(GFNPB * ppb)
  41. {
  42. PDev* ppdev = ppb->ppdev;
  43. Surf* psurfDst = ppb->psurfDst;
  44. RECTL* prcl = ppb->pRects;
  45. LONG c = ppb->lNumRects;
  46. RECTL* prclDst = ppb->prclDst;
  47. RECTL* prclSrc = ppb->prclSrc;
  48. DWORD dwRenderDirection;
  49. UCHAR ucAlpha = ppb->ucAlpha;
  50. SURFOBJ* psoSrc = ppb->psoSrc;
  51. ULONG* pBuffer;
  52. DBG_GDI((6, "vAlphaBlendDownload called"));
  53. ASSERTDD(ppdev->cPelSize != 0,
  54. "vAlphaBlend: expect not to be in 8bpp mode");
  55. ASSERTDD(psoSrc->iBitmapFormat == BMF_32BPP,
  56. "vAlphaBlend: expect source bitmap format to be 32bpp");
  57. InputBufferReserve(ppdev, 20, &pBuffer);
  58. pBuffer[0] = __Permedia2TagDitherMode;
  59. pBuffer[1] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
  60. (ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
  61. (ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
  62. (1 << PM_DITHERMODE_ENABLE);
  63. pBuffer[2] = __Permedia2TagAlphaBlendMode;
  64. pBuffer[3] = (1 << PM_ALPHABLENDMODE_BLENDTYPE) | // ramp
  65. (1 << PM_ALPHABLENDMODE_COLORORDER) | // RGB
  66. (1 << PM_ALPHABLENDMODE_ENABLE) |
  67. (81 << PM_ALPHABLENDMODE_OPERATION) | // PreMult
  68. (ppdev->ulPermFormat << PM_ALPHABLENDMODE_COLORFORMAT) |
  69. (ppdev->ulPermFormatEx << PM_ALPHABLENDMODE_COLORFORMATEXTENSION);
  70. // Reject range
  71. pBuffer[4] = __Permedia2TagFBWindowBase;
  72. pBuffer[5] = psurfDst->ulPixOffset;
  73. // set no read of source.
  74. pBuffer[6] = __Permedia2TagFBReadMode;
  75. pBuffer[7] = 0x400 | psurfDst->ulPackedPP;
  76. pBuffer[8] = __Permedia2TagLogicalOpMode;
  77. pBuffer[9] = __PERMEDIA_DISABLE;
  78. pBuffer[10] = __Permedia2TagTextureColorMode;
  79. pBuffer[11] = (1 << PM_TEXCOLORMODE_ENABLE) |
  80. (0 << 4) | // RGB
  81. (0 << 1) ; // Modulate
  82. pBuffer[12] = __Permedia2TagTextureDataFormat;
  83. pBuffer[13] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
  84. (ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
  85. (COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER);
  86. pBuffer[14] = __Permedia2TagColorDDAMode;
  87. pBuffer[15] = 1;
  88. pBuffer[16] = __Permedia2TagConstantColor;
  89. pBuffer[17] = ucAlpha << 24 | ucAlpha << 16 | ucAlpha << 8 | ucAlpha;
  90. pBuffer[18] = __Permedia2TagTextureReadMode;
  91. pBuffer[19] = PM_TEXREADMODE_ENABLE(__PERMEDIA_DISABLE);
  92. pBuffer += 20;
  93. InputBufferCommit(ppdev, pBuffer);
  94. while(c--)
  95. {
  96. InputBufferReserve(ppdev, 12, &pBuffer);
  97. pBuffer[0] = __Permedia2TagStartXDom;
  98. pBuffer[1] = prcl->left << 16;
  99. pBuffer[2] = __Permedia2TagStartXSub;
  100. pBuffer[3] = prcl->right << 16;
  101. pBuffer[4] = __Permedia2TagStartY;
  102. pBuffer[5] = prcl->top << 16;
  103. pBuffer[6] = __Permedia2TagdY;
  104. pBuffer[7] = 1 << 16;
  105. pBuffer[8] = __Permedia2TagCount;
  106. pBuffer[9] = prcl->bottom - prcl->top;
  107. pBuffer[10] = __Permedia2TagRender;
  108. pBuffer[11] = __RENDER_TRAPEZOID_PRIMITIVE
  109. | __RENDER_TEXTURED_PRIMITIVE
  110. | __RENDER_SYNC_ON_HOST_DATA;
  111. pBuffer += 12;
  112. InputBufferCommit(ppdev, pBuffer);
  113. // download data
  114. {
  115. LONG xOffset = prclSrc->left + (prcl->left - prclDst->left);
  116. LONG yOffset = prclSrc->top + (prcl->top - prclDst->top);
  117. ULONG * pulTexel = (ULONG *) psoSrc->pvScan0;
  118. ULONG ulWidth = prcl->right - prcl->left;
  119. ULONG ulHeight = prcl->bottom - prcl->top;
  120. LONG ulPixDelta = psoSrc->lDelta >> 2;
  121. LONG ulScanSkip = ulPixDelta - ulWidth;
  122. ULONG* pulSentinel;
  123. ASSERTDD(psoSrc->pvScan0 != NULL, "pvScan0 is null");
  124. ASSERTDD((psoSrc->lDelta & 3) == 0, "lDelta not multiple of four");
  125. ASSERTDD(xOffset >= 0, "xOffset is negative");
  126. ASSERTDD(yOffset >= 0, "yOffset is negative");
  127. ASSERTDD(ulWidth < MAX_INPUT_BUFFER_RESERVATION,
  128. "vAlphaBlendDownload: width is too large");
  129. pulTexel += xOffset;
  130. pulTexel += ulPixDelta * yOffset;
  131. while(ulHeight--)
  132. {
  133. pulSentinel = pulTexel + ulWidth;
  134. InputBufferReserve(ppdev, ulWidth + 1, &pBuffer);
  135. *pBuffer++ = __Permedia2TagTexel0 | ((ulWidth - 1) << 16);
  136. while(pulTexel < pulSentinel)
  137. {
  138. ULONG texel = *pulTexel++;
  139. *pBuffer++ = SWAP_BR(texel);
  140. }
  141. InputBufferCommit(ppdev, pBuffer);
  142. pulTexel += ulScanSkip;
  143. }
  144. }
  145. prcl++;
  146. }
  147. //
  148. // Always restore default state
  149. //
  150. InputBufferReserve(ppdev, 16, &pBuffer);
  151. pBuffer[0] = __Permedia2TagdY;
  152. pBuffer[1] = INTtoFIXED(1);
  153. pBuffer[2] = __Permedia2TagDitherMode;
  154. pBuffer[3] = 0;
  155. pBuffer[4] = __Permedia2TagYUVMode;
  156. pBuffer[5] = 0;
  157. pBuffer[6] = __Permedia2TagTextureAddressMode;
  158. pBuffer[7] = __PERMEDIA_DISABLE;
  159. pBuffer[8] = __Permedia2TagTextureColorMode;
  160. pBuffer[9] = __PERMEDIA_DISABLE;
  161. pBuffer[10] = __Permedia2TagTextureReadMode;
  162. pBuffer[11] = __PERMEDIA_DISABLE;
  163. pBuffer[12] = __Permedia2TagAlphaBlendMode;
  164. pBuffer[13] = __PERMEDIA_DISABLE;
  165. pBuffer[14] = __Permedia2TagColorDDAMode;
  166. pBuffer[15] = __PERMEDIA_DISABLE;
  167. pBuffer += 16;
  168. InputBufferCommit(ppdev, pBuffer);
  169. }// vAlphaBlend()
  170. //-----------------------------------------------------------------------------
  171. //
  172. // void vConstantAlphaBlend(GFNPB * ppb)
  173. //
  174. // Using constant blend factor to apply to the entire source surface
  175. //
  176. // Argumentes needed from function block (GFNPB)
  177. // ppdev-------PPDev
  178. // psurfSrc----Source surface
  179. // psurfDst----Destination surface
  180. // pRects------Pointer to a list of rectangles information which needed to be
  181. // filled
  182. // lNumRects---Number of rectangles to fill
  183. // prclDst-----Points to a RECTL structure that defines the rectangular area
  184. // to be modified
  185. // prclSrc-----Points to a RECTL structure that defines the rectangular area
  186. // to be copied
  187. // ucAlpha-----Alpha value
  188. //
  189. //-----------------------------------------------------------------------------
  190. VOID
  191. vConstantAlphaBlend(GFNPB * ppb)
  192. {
  193. PDev* ppdev = ppb->ppdev;
  194. Surf* psurfSrc = ppb->psurfSrc;
  195. Surf* psurfDst = ppb->psurfDst;
  196. RECTL* prcl = ppb->pRects;
  197. LONG c = ppb->lNumRects;
  198. RECTL* prclDst = ppb->prclDst;
  199. RECTL* prclSrc = ppb->prclSrc;
  200. DWORD dwRenderDirection;
  201. UCHAR alpha = ppb->ucAlpha;
  202. ULONG* pBuffer;
  203. DBG_GDI((6,"vConstantAlphaBlend called"));
  204. ASSERTDD(ppdev->cPelSize != 0,
  205. "vAlphaBlend: expect not to be in 8bpp mode");
  206. // setup loop invariant state
  207. InputBufferReserve(ppdev, 26, &pBuffer);
  208. pBuffer[0] = __Permedia2TagDitherMode;
  209. pBuffer[1] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
  210. (ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
  211. (ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
  212. (1 << PM_DITHERMODE_ENABLE);
  213. pBuffer[2] = __Permedia2TagAlphaBlendMode;
  214. pBuffer[3] = ppdev->ulPermFormat << 8 |
  215. ppdev->ulPermFormatEx << 16 |
  216. ( 1 << 0 ) | // enable blending
  217. ( 1 << 13) | // color order: BGR=0, RGB=1
  218. ( 1 << 14) | // BlendType: RGB=0, Ramp=1
  219. (84 << 1); // Operation: Blend=84, PreMult=81
  220. // Reject range
  221. pBuffer[4] = __Permedia2TagFBWindowBase;
  222. pBuffer[5] = psurfDst->ulPixOffset;
  223. // set no read of source.
  224. pBuffer[6] = __Permedia2TagFBReadMode;
  225. pBuffer[7] = 0x400 // read destination enable
  226. | psurfDst->ulPackedPP;
  227. pBuffer[8] = __Permedia2TagLogicalOpMode;
  228. pBuffer[9] = __PERMEDIA_DISABLE;
  229. // set base of source
  230. pBuffer[10] = __Permedia2TagTextureBaseAddress;
  231. pBuffer[11] = psurfSrc->ulPixOffset;
  232. pBuffer[12] = __Permedia2TagTextureAddressMode;
  233. pBuffer[13] = (1 << PM_TEXADDRESSMODE_ENABLE);
  234. pBuffer[14] = __Permedia2TagTextureColorMode;
  235. pBuffer[15] = (1 << PM_TEXCOLORMODE_ENABLE) |
  236. (0 << 4) | // RGB
  237. (0 << 1); // Modulate
  238. pBuffer[16] = __Permedia2TagTextureReadMode;
  239. pBuffer[17] = PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
  240. PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE) |
  241. PM_TEXREADMODE_WIDTH(11) |
  242. PM_TEXREADMODE_HEIGHT(11);
  243. pBuffer[18] = __Permedia2TagTextureDataFormat;
  244. pBuffer[19] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
  245. (ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
  246. (COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER) |
  247. (1 << 4); // no alpha
  248. pBuffer[20] = __Permedia2TagTextureMapFormat;
  249. pBuffer[21] = (psurfSrc->ulPackedPP) |
  250. (ppdev->cPelSize << PM_TEXMAPFORMAT_TEXELSIZE);
  251. pBuffer[22] = __Permedia2TagColorDDAMode;
  252. pBuffer[23] = 1;
  253. pBuffer[24] = __Permedia2TagConstantColor;
  254. pBuffer[25] = alpha << 24 | 0xffffff ;
  255. pBuffer += 26;
  256. InputBufferCommit(ppdev, pBuffer);
  257. while(c--)
  258. {
  259. RECTL rDest;
  260. RECTL rSrc;
  261. rDest = *prcl;
  262. rSrc.left = prclSrc->left + (rDest.left - prclDst->left);
  263. rSrc.top = prclSrc->top + (rDest.top - prclDst->top);
  264. rSrc.right = rSrc.left + (rDest.right - rDest.left);
  265. rSrc.bottom = rSrc.top + (rDest.bottom - rDest.top);
  266. if (rSrc.top < 0) {
  267. rDest.top -= rSrc.top;
  268. rSrc.top = 0;
  269. }
  270. if (rSrc.left < 0) {
  271. rDest.left -= rSrc.left;
  272. rSrc.left = 0;
  273. }
  274. //@@BEGIN_DDKSPLIT
  275. // TODO: remove some of the magic values
  276. //@@END_DDKSPLIT
  277. if (psurfSrc->ulPixOffset != psurfDst->ulPixOffset)
  278. {
  279. dwRenderDirection = 1;
  280. }
  281. else
  282. {
  283. if(rSrc.top < rDest.top)
  284. {
  285. dwRenderDirection = 0;
  286. }
  287. else if(rSrc.top > rDest.top)
  288. {
  289. dwRenderDirection = 1;
  290. }
  291. else if(rSrc.left < rDest.left)
  292. {
  293. dwRenderDirection = 0;
  294. }
  295. else dwRenderDirection = 1;
  296. }
  297. InputBufferReserve(ppdev, 24, &pBuffer);
  298. // Left -> right, top->bottom
  299. if (dwRenderDirection)
  300. {
  301. // set offset of source
  302. pBuffer[0] = __Permedia2TagSStart;
  303. pBuffer[1] = rSrc.left << 20;
  304. pBuffer[2] = __Permedia2TagTStart;
  305. pBuffer[3] = rSrc.top << 20;
  306. pBuffer[4] = __Permedia2TagdSdx;
  307. pBuffer[5] = 1 << 20;
  308. pBuffer[6] = __Permedia2TagdSdyDom;
  309. pBuffer[7] = 0;
  310. pBuffer[8] = __Permedia2TagdTdx;
  311. pBuffer[9] = 0;
  312. pBuffer[10] = __Permedia2TagdTdyDom;
  313. pBuffer[11] = 1 << 20;
  314. pBuffer[12] = __Permedia2TagStartXDom;
  315. pBuffer[13] = rDest.left << 16;
  316. pBuffer[14] = __Permedia2TagStartXSub;
  317. pBuffer[15] = rDest.right << 16;
  318. pBuffer[16] = __Permedia2TagStartY;
  319. pBuffer[17] = rDest.top << 16;
  320. pBuffer[18] = __Permedia2TagdY;
  321. pBuffer[19] = 1 << 16;
  322. pBuffer[20] = __Permedia2TagCount;
  323. pBuffer[21] = rDest.bottom - rDest.top;
  324. pBuffer[22] = __Permedia2TagRender;
  325. pBuffer[23] = __RENDER_TRAPEZOID_PRIMITIVE
  326. | __RENDER_TEXTURED_PRIMITIVE;
  327. }
  328. else
  329. // right->left, bottom->top
  330. {
  331. // set offset of source
  332. pBuffer[0] = __Permedia2TagSStart;
  333. pBuffer[1] = rSrc.right << 20;
  334. pBuffer[2] = __Permedia2TagTStart;
  335. pBuffer[3] = (rSrc.bottom - 1) << 20;
  336. pBuffer[4] = __Permedia2TagdSdx;
  337. pBuffer[5] = (DWORD)(-1 << 20);
  338. pBuffer[6] = __Permedia2TagdSdyDom;
  339. pBuffer[7] = 0;
  340. pBuffer[8] = __Permedia2TagdTdx;
  341. pBuffer[9] = 0;
  342. pBuffer[10] = __Permedia2TagdTdyDom;
  343. pBuffer[11] = (DWORD)(-1 << 20);
  344. // Render right to left, bottom to top
  345. pBuffer[12] = __Permedia2TagStartXDom;
  346. pBuffer[13] = rDest.right << 16;
  347. pBuffer[14] = __Permedia2TagStartXSub;
  348. pBuffer[15] = rDest.left << 16;
  349. pBuffer[16] = __Permedia2TagStartY;
  350. pBuffer[17] = (rDest.bottom - 1) << 16;
  351. pBuffer[18] = __Permedia2TagdY;
  352. pBuffer[19] = (DWORD)(-1 << 16);
  353. pBuffer[20] = __Permedia2TagCount;
  354. pBuffer[21] = rDest.bottom - rDest.top;
  355. pBuffer[22] = __Permedia2TagRender;
  356. pBuffer[23] = __RENDER_TRAPEZOID_PRIMITIVE
  357. | __RENDER_TEXTURED_PRIMITIVE;
  358. }
  359. pBuffer += 24;
  360. InputBufferCommit(ppdev, pBuffer);
  361. prcl++;
  362. }
  363. InputBufferReserve(ppdev, 20, &pBuffer);
  364. pBuffer[0] = __Permedia2TagdY;
  365. pBuffer[1] = INTtoFIXED(1);
  366. pBuffer[2] = __Permedia2TagDitherMode;
  367. pBuffer[3] = 0;
  368. pBuffer[4] = __Permedia2TagYUVMode;
  369. pBuffer[5] = 0;
  370. pBuffer[6] = __Permedia2TagTextureAddressMode;
  371. pBuffer[7] = __PERMEDIA_DISABLE;
  372. pBuffer[8] = __Permedia2TagTextureColorMode;
  373. pBuffer[9] = __PERMEDIA_DISABLE;
  374. pBuffer[10] = __Permedia2TagTextureReadMode;
  375. pBuffer[11] = __PERMEDIA_DISABLE;
  376. pBuffer[12] = __Permedia2TagAlphaBlendMode;
  377. pBuffer[13] = __PERMEDIA_DISABLE;
  378. pBuffer[14] = __Permedia2TagColorDDAMode;
  379. pBuffer[15] = __PERMEDIA_DISABLE;
  380. pBuffer[16] = __Permedia2TagTextureDataFormat;
  381. pBuffer[17] = __PERMEDIA_DISABLE;
  382. pBuffer[18] = __Permedia2TagTextureMapFormat;
  383. pBuffer[19] = __PERMEDIA_DISABLE;
  384. pBuffer += 20;
  385. InputBufferCommit(ppdev, pBuffer);
  386. }// vConstantAlphaBlend()
  387. //-----------------------------------------------------------------------------
  388. //
  389. // void vAlphaBlend(GFNPB * ppb)
  390. //
  391. // Doing an alpha blend on a source surface which is in a pre-multiplied alpha
  392. // 32bpp "BGRA" format; that is, the surface type is BMF_32BPP and the palette
  393. // type is BI_RGB.
  394. //
  395. // Argumentes needed from function block (GFNPB)
  396. // ppdev-------PPDev
  397. // psurfSrc----Source surface
  398. // psurfDst----Destination surface
  399. // pRects------Pointer to a list of rectangles information which needed to be
  400. // filled
  401. // lNumRects---Number of rectangles to fill
  402. // prclDst-----Points to a RECTL structure that defines the rectangular area
  403. // to be modified
  404. // prclSrc-----Points to a RECTL structure that defines the rectangular area
  405. // to be copied
  406. // ucAlpha-----Alpha value
  407. //
  408. //-----------------------------------------------------------------------------
  409. VOID
  410. vAlphaBlend(GFNPB * ppb)
  411. {
  412. PDev* ppdev = ppb->ppdev;
  413. Surf* psurfSrc = ppb->psurfSrc;
  414. Surf* psurfDst = ppb->psurfDst;
  415. RECTL* prcl = ppb->pRects;
  416. LONG c = ppb->lNumRects;
  417. RECTL* prclDst = ppb->prclDst;
  418. RECTL* prclSrc = ppb->prclSrc;
  419. DWORD dwRenderDirection;
  420. UCHAR ucAlpha = ppb->ucAlpha;
  421. ULONG* pBuffer;
  422. DBG_GDI((6, "vAlphaBlend called"));
  423. DBG_GDI((7,"vAlphaBlend"));
  424. ASSERTDD(ppdev->cPelSize != 0,
  425. "vAlphaBlend: expect not to be in 8bpp mode");
  426. InputBufferReserve(ppdev, 26, &pBuffer);
  427. pBuffer[0] = __Permedia2TagDitherMode;
  428. pBuffer[1] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
  429. (ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
  430. (ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
  431. (1 << PM_DITHERMODE_ENABLE);
  432. pBuffer[2] = __Permedia2TagAlphaBlendMode;
  433. pBuffer[3] = (1 << PM_ALPHABLENDMODE_BLENDTYPE) | // ramp
  434. (1 << PM_ALPHABLENDMODE_COLORORDER) | // RGB
  435. (1 << PM_ALPHABLENDMODE_ENABLE) |
  436. (81 << PM_ALPHABLENDMODE_OPERATION) | // PreMult
  437. (ppdev->ulPermFormat << PM_ALPHABLENDMODE_COLORFORMAT) |
  438. (ppdev->ulPermFormatEx << PM_ALPHABLENDMODE_COLORFORMATEXTENSION);
  439. // Reject range
  440. pBuffer[4] = __Permedia2TagFBWindowBase;
  441. pBuffer[5] = psurfDst->ulPixOffset;
  442. // set no read of source.
  443. pBuffer[6] = __Permedia2TagFBReadMode;
  444. pBuffer[7] = 0x400 | psurfDst->ulPackedPP;
  445. pBuffer[8] = __Permedia2TagLogicalOpMode;
  446. pBuffer[9] = __PERMEDIA_DISABLE;
  447. // set base of source
  448. pBuffer[10] = __Permedia2TagTextureBaseAddress;
  449. pBuffer[11] = psurfSrc->ulPixOffset;
  450. pBuffer[12] = __Permedia2TagTextureAddressMode;
  451. pBuffer[13] = (1 << PM_TEXADDRESSMODE_ENABLE);
  452. pBuffer[14] = __Permedia2TagTextureColorMode;
  453. pBuffer[15] = (1 << PM_TEXCOLORMODE_ENABLE) |
  454. (0 << 4) | // RGB
  455. (0 << 1); // Modulate
  456. pBuffer[16] = __Permedia2TagTextureReadMode;
  457. pBuffer[17] = PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
  458. PM_TEXREADMODE_FILTER(__PERMEDIA_DISABLE) |
  459. PM_TEXREADMODE_WIDTH(11) |
  460. PM_TEXREADMODE_HEIGHT(11);
  461. pBuffer[18] = __Permedia2TagTextureDataFormat;
  462. pBuffer[19] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
  463. (ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
  464. (COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER);
  465. pBuffer[20] = __Permedia2TagTextureMapFormat;
  466. pBuffer[21] = (psurfSrc->ulPackedPP) |
  467. (ppdev->cPelSize << PM_TEXMAPFORMAT_TEXELSIZE);
  468. pBuffer[22] = __Permedia2TagColorDDAMode;
  469. pBuffer[23] = 1;
  470. pBuffer[24] = __Permedia2TagConstantColor;
  471. pBuffer[25] = ucAlpha << 24 | ucAlpha << 16 | ucAlpha << 8 | ucAlpha;
  472. pBuffer += 26;
  473. InputBufferCommit(ppdev, pBuffer);
  474. while(c--)
  475. {
  476. RECTL rDest;
  477. RECTL rSrc;
  478. rDest = *prcl;
  479. rSrc.left = prclSrc->left + (rDest.left - prclDst->left);
  480. rSrc.top = prclSrc->top + (rDest.top - prclDst->top);
  481. rSrc.right = rSrc.left + (rDest.right - rDest.left);
  482. rSrc.bottom = rSrc.top + (rDest.bottom - rDest.top);
  483. if (rSrc.top < 0) {
  484. rDest.top -= rSrc.top;
  485. rSrc.top = 0;
  486. }
  487. if (rSrc.left < 0) {
  488. rDest.left -= rSrc.left;
  489. rSrc.left = 0;
  490. }
  491. //@@BEGIN_DDKSPLIT
  492. // TODO: use continuation to save permedia writes
  493. // TODO: remove some of the magic values
  494. //@@END_DDKSPLIT
  495. if (psurfSrc->ulPixOffset != psurfDst->ulPixOffset)
  496. {
  497. dwRenderDirection = 1;
  498. }
  499. else
  500. {
  501. if(rSrc.top < rDest.top)
  502. {
  503. dwRenderDirection = 0;
  504. }
  505. else if(rSrc.top > rDest.top)
  506. {
  507. dwRenderDirection = 1;
  508. }
  509. else if(rSrc.left < rDest.left)
  510. {
  511. dwRenderDirection = 0;
  512. }
  513. else dwRenderDirection = 1;
  514. }
  515. /*
  516. * Render the rectangle
  517. */
  518. InputBufferReserve(ppdev, 24, &pBuffer);
  519. // Left -> right, top->bottom
  520. if (dwRenderDirection)
  521. {
  522. // set offset of source
  523. pBuffer[0] = __Permedia2TagSStart;
  524. pBuffer[1] = rSrc.left << 20;
  525. pBuffer[2] = __Permedia2TagTStart;
  526. pBuffer[3] = rSrc.top << 20;
  527. pBuffer[4] = __Permedia2TagdSdx;
  528. pBuffer[5] = 1 << 20;
  529. pBuffer[6] = __Permedia2TagdSdyDom;
  530. pBuffer[7] = 0;
  531. pBuffer[8] = __Permedia2TagdTdx;
  532. pBuffer[9] = 0;
  533. pBuffer[10] = __Permedia2TagdTdyDom;
  534. pBuffer[11] = 1 << 20;
  535. pBuffer[12] = __Permedia2TagStartXDom;
  536. pBuffer[13] = rDest.left << 16;
  537. pBuffer[14] = __Permedia2TagStartXSub;
  538. pBuffer[15] = rDest.right << 16;
  539. pBuffer[16] = __Permedia2TagStartY;
  540. pBuffer[17] = rDest.top << 16;
  541. pBuffer[18] = __Permedia2TagdY;
  542. pBuffer[19] = 1 << 16;
  543. pBuffer[20] = __Permedia2TagCount;
  544. pBuffer[21] = rDest.bottom - rDest.top;
  545. pBuffer[22] = __Permedia2TagRender;
  546. pBuffer[23] = __RENDER_TRAPEZOID_PRIMITIVE
  547. | __RENDER_TEXTURED_PRIMITIVE;
  548. }
  549. else
  550. // right->left, bottom->top
  551. {
  552. // set offset of source
  553. pBuffer[0] = __Permedia2TagSStart;
  554. pBuffer[1] = rSrc.right << 20;
  555. pBuffer[2] = __Permedia2TagTStart;
  556. pBuffer[3] = (rSrc.bottom - 1) << 20;
  557. pBuffer[4] = __Permedia2TagdSdx;
  558. pBuffer[5] = (DWORD)(-1 << 20);
  559. pBuffer[6] = __Permedia2TagdSdyDom;
  560. pBuffer[7] = 0;
  561. pBuffer[8] = __Permedia2TagdTdx;
  562. pBuffer[9] = 0;
  563. pBuffer[10] = __Permedia2TagdTdyDom;
  564. pBuffer[11] = (DWORD)(-1 << 20);
  565. // Render right to left, bottom to top
  566. pBuffer[12] = __Permedia2TagStartXDom;
  567. pBuffer[13] = rDest.right << 16;
  568. pBuffer[14] = __Permedia2TagStartXSub;
  569. pBuffer[15] = rDest.left << 16;
  570. pBuffer[16] = __Permedia2TagStartY;
  571. pBuffer[17] = (rDest.bottom - 1) << 16;
  572. pBuffer[18] = __Permedia2TagdY;
  573. pBuffer[19] = (DWORD)(-1 << 16);
  574. pBuffer[20] = __Permedia2TagCount;
  575. pBuffer[21] = rDest.bottom - rDest.top;
  576. pBuffer[22] = __Permedia2TagRender;
  577. pBuffer[23] = __RENDER_TRAPEZOID_PRIMITIVE
  578. | __RENDER_TEXTURED_PRIMITIVE;
  579. }
  580. pBuffer += 24;
  581. InputBufferCommit(ppdev, pBuffer);
  582. prcl++;
  583. }
  584. //
  585. // Always restore default state
  586. //
  587. InputBufferReserve(ppdev, 16, &pBuffer);
  588. pBuffer[0] = __Permedia2TagdY;
  589. pBuffer[1] = INTtoFIXED(1);
  590. pBuffer[2] = __Permedia2TagDitherMode;
  591. pBuffer[3] = 0;
  592. pBuffer[4] = __Permedia2TagYUVMode;
  593. pBuffer[5] = 0;
  594. pBuffer[6] = __Permedia2TagTextureAddressMode;
  595. pBuffer[7] = __PERMEDIA_DISABLE;
  596. pBuffer[8] = __Permedia2TagTextureColorMode;
  597. pBuffer[9] = __PERMEDIA_DISABLE;
  598. pBuffer[10] = __Permedia2TagTextureReadMode;
  599. pBuffer[11] = __PERMEDIA_DISABLE;
  600. pBuffer[12] = __Permedia2TagAlphaBlendMode;
  601. pBuffer[13] = __PERMEDIA_DISABLE;
  602. pBuffer[14] = __Permedia2TagColorDDAMode;
  603. pBuffer[15] = __PERMEDIA_DISABLE;
  604. pBuffer += 16;
  605. InputBufferCommit(ppdev, pBuffer);
  606. }// vAlphaBlend()
  607. //-----------------------------------------------------------------------------
  608. //
  609. // VOID vCopyBlt(GFNPB* ppb)
  610. //
  611. // Does a screen-to-screen copy blt of a list of rectangles.
  612. //
  613. // Argumentes needed from function block (GFNPB)
  614. // ppdev-------PPDev
  615. // psurfSrc----Source surface
  616. // psurfDst----Destination surface
  617. // pRects------Pointer to a list of rectangles information which needed to be
  618. // filled
  619. // lNumRects---Number of rectangles to fill
  620. // prclDst-----Points to a RECTL structure that defines the rectangular area
  621. // to be modified
  622. // pptlSrc-----Original unclipped source point
  623. //
  624. //-----------------------------------------------------------------------------
  625. VOID
  626. vCopyBlt(GFNPB* ppb)
  627. {
  628. PDev* ppdev = ppb->ppdev;
  629. Surf* psurfSrc = ppb->psurfSrc;
  630. Surf* psurfDst = ppb->psurfDst;
  631. RECTL* prcl = ppb->pRects;
  632. LONG c = ppb->lNumRects;
  633. RECTL* prclDst = ppb->prclDst;
  634. POINTL* pptlSrc = ppb->pptlSrc;
  635. DWORD renderBits = __RENDER_TRAPEZOID_PRIMITIVE;
  636. DWORD offset;
  637. LONG sourceOffset;
  638. DWORD windowBase;
  639. LONG windowOffset;
  640. ULONG DestPitch = psurfDst->ulPixDelta;
  641. ULONG SourcePitch = psurfSrc->ulPixDelta;
  642. BOOL bEnablePacked = TRUE;
  643. ULONG ulLogicOP = ulRop2ToLogicop(ppb->ulRop4 & 0xf);
  644. DBG_GDI((6, "vCopyBlt called"));
  645. windowBase = psurfDst->ulPixOffset;
  646. windowOffset = (LONG) (psurfSrc->ulPixOffset - psurfDst->ulPixOffset);
  647. // BUGFIX: Permedia hardware bug
  648. // We can not enable if we have an overlapping blt with not vertical shift
  649. // and a horizontal shift less or equal to ppdev->dwBppMask
  650. if (psurfSrc == psurfDst && prclDst->top == pptlSrc->y)
  651. {
  652. LONG xShift = prclDst->left - pptlSrc->x;
  653. if(xShift >= 0 && xShift <= (LONG) ppdev->dwBppMask)
  654. bEnablePacked = FALSE;
  655. }
  656. // BUGFIX: Permedia hardware bug???
  657. // We have intermittent failures of the copy operation
  658. // when going from the screen to offscreen where the first
  659. // four bytes (when in 8bpp) of every row are not copied.
  660. // For now, I'm disabling until we can talk with the permedia folks.
  661. bEnablePacked = FALSE;
  662. // setup loop invariant state
  663. ULONG* pBuffer;
  664. InputBufferReserve(ppdev, 4, &pBuffer);
  665. pBuffer[0] = __Permedia2TagLogicalOpMode;
  666. pBuffer[1] = P2_ENABLED_LOGICALOP(ulLogicOP);
  667. pBuffer[2] = __Permedia2TagFBWindowBase;
  668. pBuffer[3] = windowBase;
  669. pBuffer += 4;
  670. InputBufferCommit(ppdev, pBuffer);
  671. while(c--) {
  672. RECTL rDest;
  673. RECTL rSrc;
  674. rDest = *prcl;
  675. rSrc.left = pptlSrc->x + (rDest.left - prclDst->left);
  676. rSrc.top = pptlSrc->y + (rDest.top - prclDst->top);
  677. rSrc.right = rSrc.left + (rDest.right - rDest.left);
  678. rSrc.bottom = rSrc.top + (rDest.bottom - rDest.top);
  679. if (rSrc.top < 0) {
  680. rDest.top -= rSrc.top;
  681. rSrc.top = 0;
  682. }
  683. if (rSrc.left < 0) {
  684. rDest.left -= rSrc.left;
  685. rSrc.left = 0;
  686. }
  687. if(bEnablePacked)
  688. {
  689. offset = (((rDest.left & ppdev->dwBppMask)
  690. - (rSrc.left & ppdev->dwBppMask)) & 7);
  691. sourceOffset = windowOffset
  692. + ((rSrc.top * SourcePitch) + (rSrc.left & ~(ppdev->dwBppMask)))
  693. - ((rDest.top * DestPitch) + (rDest.left & ~(ppdev->dwBppMask)))
  694. + ((DestPitch - SourcePitch) * rDest.top);
  695. }
  696. else
  697. {
  698. offset = 0;
  699. sourceOffset = windowOffset + ((rSrc.top * SourcePitch) + rSrc.left)
  700. - ((rDest.top * DestPitch) + rDest.left)
  701. + ((DestPitch - SourcePitch) * rDest.top);
  702. }
  703. // P2_DEFAULT_FB_DEPTH;
  704. ULONG readMode = PM_FBREADMODE_PARTIAL(psurfSrc->ulPackedPP) |
  705. PM_FBREADMODE_READSOURCE(__PERMEDIA_ENABLE) |
  706. PM_FBREADMODE_RELATIVEOFFSET(offset) |
  707. LogicopReadDest[ulLogicOP];
  708. ULONG writeConfig = PM_FBREADMODE_PARTIAL(psurfDst->ulPackedPP) |
  709. PM_FBREADMODE_READSOURCE(__PERMEDIA_ENABLE) |
  710. PM_FBREADMODE_RELATIVEOFFSET(offset) |
  711. LogicopReadDest[ulLogicOP];
  712. if(bEnablePacked)
  713. {
  714. readMode |= PM_FBREADMODE_PACKEDDATA(__PERMEDIA_ENABLE);
  715. writeConfig |= PM_FBREADMODE_PACKEDDATA(__PERMEDIA_ENABLE);
  716. }
  717. // Render the rectangle
  718. ULONG startXDom;
  719. ULONG startXSub;
  720. ULONG packedDataLimits;
  721. ULONG startY;
  722. ULONG dy;
  723. if (sourceOffset >= 0) {
  724. // Use left to right and top to bottom
  725. if(bEnablePacked)
  726. {
  727. startXDom = (rDest.left >> ppdev->bBppShift) << 16;
  728. startXSub = ((rDest.right >> ppdev->bBppShift)
  729. + ppdev->dwBppMask) << 16;
  730. packedDataLimits = PM_PACKEDDATALIMITS_OFFSET(offset) |
  731. PM_PACKEDDATALIMITS_XSTART(rDest.left) |
  732. PM_PACKEDDATALIMITS_XEND(rDest.right);
  733. }
  734. else
  735. {
  736. startXDom = rDest.left << 16;
  737. startXSub = rDest.right << 16;
  738. }
  739. startY = rDest.top << 16;
  740. dy = 1 << 16;
  741. }
  742. else
  743. {
  744. // Use right to left and bottom to top
  745. if(bEnablePacked)
  746. {
  747. startXDom = (((rDest.right) >> ppdev->bBppShift)
  748. + ppdev->dwBppMask) << 16;
  749. startXSub = (rDest.left >> ppdev->bBppShift) << 16;
  750. packedDataLimits = PM_PACKEDDATALIMITS_OFFSET(offset) |
  751. PM_PACKEDDATALIMITS_XSTART(rDest.right) |
  752. PM_PACKEDDATALIMITS_XEND(rDest.left);
  753. }
  754. else
  755. {
  756. startXDom = rDest.right << 16;
  757. startXSub = rDest.left << 16;
  758. }
  759. startY = (rDest.bottom - 1) << 16;
  760. dy = (DWORD)((-1) << 16);
  761. }
  762. ULONG count = rDest.bottom - rDest.top;
  763. InputBufferReserve(ppdev, 18, &pBuffer);
  764. pBuffer[0] = __Permedia2TagFBSourceOffset;
  765. pBuffer[1] = sourceOffset;
  766. pBuffer[2] = __Permedia2TagFBReadMode;
  767. pBuffer[3] = readMode;
  768. pBuffer[4] = __Permedia2TagFBWriteConfig;
  769. pBuffer[5] = writeConfig;
  770. pBuffer[6] = __Permedia2TagStartXDom;
  771. pBuffer[7] = startXDom;
  772. pBuffer[8] = __Permedia2TagStartXSub;
  773. pBuffer[9] = startXSub;
  774. #if 0
  775. if(bEnablePacked)
  776. {
  777. pBuffer[0] = __Permedia2TagPackedDataLimits;
  778. pBuffer[1] = packedDataLimits;
  779. }
  780. #endif
  781. pBuffer[10] = __Permedia2TagStartY;
  782. pBuffer[11] = startY;
  783. pBuffer[12] = __Permedia2TagdY;
  784. pBuffer[13] = dy;
  785. pBuffer[14] = __Permedia2TagCount;
  786. pBuffer[15] = count;
  787. pBuffer[16] = __Permedia2TagRender;
  788. pBuffer[17] = renderBits;
  789. pBuffer += 18;
  790. InputBufferCommit(ppdev, pBuffer);
  791. prcl++;
  792. }
  793. InputBufferReserve(ppdev, 2, &pBuffer);
  794. pBuffer[0] = __Permedia2TagdY;
  795. pBuffer[1] = INTtoFIXED(1);
  796. pBuffer += 2;
  797. InputBufferCommit(ppdev, pBuffer);
  798. }// vCopyBlt()
  799. //-----------------------------------------------------------------------------
  800. //
  801. // VOID vCopyBltNative(GFNPB* ppb)
  802. //
  803. // Does a screen-to-screen copy blt of a list of rectangles.
  804. //
  805. // Note: The difference between this function and vCopyBlt() is that this
  806. // function will be called only when the source and dest has the same pitch
  807. // size. The reason is that we are using the Permedia2 packed data feature to
  808. // do a 32 bits copy. Unfortunately when the source and dest has the different
  809. // pitch, the hardware has some problems to implement it right. So in
  810. // vCopyBlt(), we have to disable PackedData copy which slows down a lot
  811. //
  812. // Argumentes needed from function block (GFNPB)
  813. // ppdev-------PPDev
  814. // psurfSrc----Source surface
  815. // psurfDst----Destination surface
  816. // pRects------Pointer to a list of rectangles information which needed to be
  817. // filled
  818. // lNumRects---Number of rectangles to fill
  819. // prclDst-----Points to a RECTL structure that defines the rectangular area
  820. // to be modified
  821. // pptlSrc-----Original unclipped source point
  822. //
  823. //-----------------------------------------------------------------------------
  824. VOID
  825. vCopyBltNative(GFNPB* ppb)
  826. {
  827. PDev* ppdev = ppb->ppdev;
  828. Surf* psurfDst = ppb->psurfDst;
  829. Surf* psurfSrc = ppb->psurfSrc;
  830. RECTL* prcl = ppb->pRects;
  831. RECTL* prclDst = ppb->prclDst;
  832. POINTL* pptlSrc = ppb->pptlSrc;
  833. LONG lNumRects = ppb->lNumRects;
  834. LONG lSourceOffset;
  835. LONG lWindowOffset;
  836. DWORD dwOffset;
  837. ULONG ulLogicOP = ulRop2ToLogicop(ppb->ulRop4 & 0xf);
  838. ULONG ulPitch = psurfDst->ulPixDelta;
  839. DBG_GDI((6, "vCopyBltNative called, ulPitch=%d", ulPitch));
  840. lWindowOffset = (LONG)(psurfSrc->ulPixOffset - psurfDst->ulPixOffset);
  841. //
  842. // Setup loop invariant state
  843. //
  844. ULONG* pBuffer;
  845. InputBufferReserve(ppdev, 4, &pBuffer);
  846. pBuffer[0] = __Permedia2TagLogicalOpMode;
  847. pBuffer[1] = P2_ENABLED_LOGICALOP(ulLogicOP);
  848. pBuffer[2] = __Permedia2TagFBWindowBase;
  849. pBuffer[3] = psurfDst->ulPixOffset;
  850. pBuffer += 4;
  851. InputBufferCommit(ppdev, pBuffer);
  852. while( lNumRects-- )
  853. {
  854. RECTL rDest;
  855. RECTL rSrc;
  856. rDest = *prcl;
  857. rSrc.left = pptlSrc->x + (rDest.left - prclDst->left);
  858. rSrc.top = pptlSrc->y + (rDest.top - prclDst->top);
  859. rSrc.right = rSrc.left + (rDest.right - rDest.left);
  860. rSrc.bottom = rSrc.top + (rDest.bottom - rDest.top);
  861. if ( rSrc.top < 0 )
  862. {
  863. rDest.top -= rSrc.top;
  864. rSrc.top = 0;
  865. }
  866. if ( rSrc.left < 0 )
  867. {
  868. rDest.left -= rSrc.left;
  869. rSrc.left = 0;
  870. }
  871. dwOffset = (((rDest.left & ppdev->dwBppMask)
  872. - (rSrc.left & ppdev->dwBppMask)) & 7);
  873. lSourceOffset = lWindowOffset
  874. + ( (rSrc.top - rDest.top) * ulPitch )
  875. + ( rSrc.left & ~(ppdev->dwBppMask) )
  876. - ( rDest.left & ~(ppdev->dwBppMask) );
  877. //
  878. // Render the rectangle
  879. //
  880. ULONG ulStartXDom;
  881. ULONG ulStartXSub;
  882. ULONG ulPackedDataLimits;
  883. ULONG ulStartY;
  884. ULONG ulDY;
  885. DBG_GDI((6, "lSourceOffset=%d", lSourceOffset));
  886. if ( lSourceOffset >= 0 )
  887. {
  888. //
  889. // Use left to right and top to bottom
  890. //
  891. ulStartXDom = (rDest.left >> ppdev->bBppShift) << 16;
  892. ulStartXSub = ((rDest.right >> ppdev->bBppShift)
  893. + ppdev->dwBppMask) << 16;
  894. ulPackedDataLimits = PM_PACKEDDATALIMITS_OFFSET(dwOffset)
  895. | (rDest.left << 16)
  896. | (rDest.right);
  897. ulStartY = rDest.top << 16;
  898. ulDY = 1 << 16;
  899. }// if ( lSourceOffset >= 0 )
  900. else
  901. {
  902. //
  903. // Use right to left and bottom to top
  904. //
  905. ulStartXDom = (((rDest.right) >> ppdev->bBppShift)
  906. + ppdev->dwBppMask) << 16;
  907. ulStartXSub = (rDest.left >> ppdev->bBppShift) << 16;
  908. ulPackedDataLimits = PM_PACKEDDATALIMITS_OFFSET(dwOffset)
  909. | (rDest.right << 16)
  910. | (rDest.left);
  911. ulStartY = (rDest.bottom - 1) << 16;
  912. ulDY = (DWORD)((-1) << 16);
  913. }// if ( lSourceOffset < 0 )
  914. InputBufferReserve(ppdev, 18, &pBuffer);
  915. pBuffer[0] = __Permedia2TagFBSourceOffset;
  916. pBuffer[1] = lSourceOffset;
  917. pBuffer[2] = __Permedia2TagFBReadMode;
  918. pBuffer[3] = PM_FBREADMODE_PARTIAL(psurfSrc->ulPackedPP)
  919. | PM_FBREADMODE_READSOURCE(__PERMEDIA_ENABLE)
  920. | PM_FBREADMODE_RELATIVEOFFSET(dwOffset)
  921. | PM_FBREADMODE_PACKEDDATA(__PERMEDIA_ENABLE)
  922. | LogicopReadDest[ulLogicOP];
  923. pBuffer[4] = __Permedia2TagPackedDataLimits;
  924. pBuffer[5] = ulPackedDataLimits;
  925. pBuffer[6] = __Permedia2TagStartXDom;
  926. pBuffer[7] = ulStartXDom;
  927. pBuffer[8] = __Permedia2TagStartXSub;
  928. pBuffer[9] = ulStartXSub;
  929. pBuffer[10] = __Permedia2TagStartY;
  930. pBuffer[11] = ulStartY;
  931. pBuffer[12] = __Permedia2TagdY;
  932. pBuffer[13] = ulDY;
  933. pBuffer[14] = __Permedia2TagCount;
  934. pBuffer[15] = rDest.bottom - rDest.top;
  935. pBuffer[16] = __Permedia2TagRender;
  936. pBuffer[17] = __RENDER_TRAPEZOID_PRIMITIVE;
  937. pBuffer += 18;
  938. InputBufferCommit(ppdev, pBuffer);
  939. prcl++;
  940. }// while( lNumRects-- )
  941. //
  942. // Restore dY register value
  943. //
  944. InputBufferReserve(ppdev, 2, &pBuffer);
  945. pBuffer[0] = __Permedia2TagdY;
  946. pBuffer[1] = INTtoFIXED(1);
  947. pBuffer += 2;
  948. InputBufferCommit(ppdev, pBuffer);
  949. }// vCopyBltNative()
  950. //-----------------------------------------------------------------------------
  951. //
  952. // VOID vRop2Blt
  953. //
  954. // Does a screen-to-screen blt of a list of rectangles.
  955. //
  956. // Argumentes needed from function block (GFNPB)
  957. // ppdev-------PPDev
  958. // psurfSrc----Source surface
  959. // psurfDst----Destination surface
  960. // pRects------Pointer to a list of rectangles information which needed to be
  961. // filled
  962. // lNumRects---Number of rectangles to fill
  963. // prclDst-----Points to a RECTL structure that defines the rectangular area
  964. // to be modified
  965. // pptlSrc-----Original unclipped source point
  966. // usRop4------Rop4
  967. //
  968. //-----------------------------------------------------------------------------
  969. VOID
  970. vRop2Blt(GFNPB * ppb)
  971. {
  972. PDev* ppdev = ppb->ppdev;
  973. Surf* psurfSrc = ppb->psurfSrc;
  974. Surf* psurfDst = ppb->psurfDst;
  975. RECTL* prcl = ppb->pRects;
  976. LONG c = ppb->lNumRects;
  977. RECTL* prclDst = ppb->prclDst;
  978. POINTL* pptlSrc = ppb->pptlSrc;
  979. ULONG ulLogicOP = ulRop2ToLogicop(ppb->ulRop4 & 0xf);
  980. ULONG* pBuffer;
  981. // PERMEDIA_DECL_VARS;
  982. // PERMEDIA_DECL_INIT;
  983. ASSERTDD(psurfSrc != psurfDst, "vRop2Blt: unexpected psurfSrc == psurfDst");
  984. InputBufferReserve(ppdev, 32, &pBuffer);
  985. pBuffer[0] = __Permedia2TagFBWindowBase;
  986. pBuffer[1] = psurfDst->ulPixOffset;
  987. pBuffer[2] = __Permedia2TagLogicalOpMode;
  988. pBuffer[3] = P2_ENABLED_LOGICALOP(ulLogicOP);
  989. pBuffer[4] = __Permedia2TagFBReadMode;
  990. pBuffer[5] = PM_FBREADMODE_PARTIAL(psurfDst->ulPackedPP)
  991. | LogicopReadDest[ulLogicOP];
  992. pBuffer[6] = __Permedia2TagFBWriteConfig;
  993. pBuffer[7] = PM_FBREADMODE_PARTIAL(psurfDst->ulPackedPP)
  994. | LogicopReadDest[ulLogicOP];
  995. pBuffer[8] = __Permedia2TagDitherMode;
  996. pBuffer[9] = (COLOR_MODE << PM_DITHERMODE_COLORORDER) |
  997. (ppdev->ulPermFormat << PM_DITHERMODE_COLORFORMAT) |
  998. (ppdev->ulPermFormatEx << PM_DITHERMODE_COLORFORMATEXTENSION) |
  999. (1 << PM_DITHERMODE_ENABLE);
  1000. pBuffer[10] = __Permedia2TagTextureAddressMode;
  1001. pBuffer[11] = (1 << PM_TEXADDRESSMODE_ENABLE);
  1002. pBuffer[12] = __Permedia2TagTextureColorMode;
  1003. pBuffer[13] = (1 << PM_TEXCOLORMODE_ENABLE) |
  1004. (0 << 4) | // RGB
  1005. (3 << 1); // Copy
  1006. pBuffer[14] = __Permedia2TagTextureReadMode;
  1007. pBuffer[15] = PM_TEXREADMODE_ENABLE(__PERMEDIA_ENABLE) |
  1008. PM_TEXREADMODE_WIDTH(11) |
  1009. PM_TEXREADMODE_HEIGHT(11);
  1010. pBuffer[16] = __Permedia2TagTextureDataFormat;
  1011. pBuffer[17] = (ppdev->ulPermFormat << PM_TEXDATAFORMAT_FORMAT) |
  1012. (ppdev->ulPermFormatEx << PM_TEXDATAFORMAT_FORMATEXTENSION) |
  1013. (COLOR_MODE << PM_TEXDATAFORMAT_COLORORDER);
  1014. pBuffer[18] = __Permedia2TagTextureMapFormat;
  1015. pBuffer[19] = (psurfSrc->ulPackedPP) |
  1016. (ppdev->cPelSize << PM_TEXMAPFORMAT_TEXELSIZE);
  1017. pBuffer[20] = __Permedia2TagSStart;
  1018. pBuffer[21] = 0;
  1019. pBuffer[22] = __Permedia2TagTStart;
  1020. pBuffer[23] = 0;
  1021. pBuffer[24] = __Permedia2TagdSdx;
  1022. pBuffer[25] = 1 << 20;
  1023. pBuffer[26] = __Permedia2TagdSdyDom;
  1024. pBuffer[27] = 0;
  1025. pBuffer[28] = __Permedia2TagdTdx;
  1026. pBuffer[29] = 0;
  1027. pBuffer[30] = __Permedia2TagdTdyDom;
  1028. pBuffer[31] = 1 << 20;
  1029. pBuffer += 32;
  1030. InputBufferCommit(ppdev, pBuffer);
  1031. while(c--) {
  1032. // Render the rectangle
  1033. ULONG ulSrcOffset = psurfSrc->ulPixOffset
  1034. + pptlSrc->x + (prcl->left - prclDst->left)
  1035. + (pptlSrc->y + (prcl->top - prclDst->top))
  1036. * psurfSrc->ulPixDelta;
  1037. InputBufferReserve(ppdev, 12, &pBuffer);
  1038. pBuffer[0] = __Permedia2TagTextureBaseAddress;
  1039. pBuffer[1] = ulSrcOffset;
  1040. pBuffer[2] = __Permedia2TagStartXDom;
  1041. pBuffer[3] = prcl->left << 16;
  1042. pBuffer[4] = __Permedia2TagStartXSub;
  1043. pBuffer[5] = prcl->right << 16;
  1044. pBuffer[6] = __Permedia2TagStartY;
  1045. pBuffer[7] = prcl->top << 16;
  1046. pBuffer[8] = __Permedia2TagCount;
  1047. pBuffer[9] = prcl->bottom - prcl->top;
  1048. pBuffer[10] = __Permedia2TagRender;
  1049. pBuffer[11] = __RENDER_TRAPEZOID_PRIMITIVE
  1050. | __RENDER_TEXTURED_PRIMITIVE;
  1051. pBuffer += 12;
  1052. InputBufferCommit(ppdev, pBuffer);
  1053. prcl++;
  1054. }
  1055. // Restore default state
  1056. InputBufferReserve(ppdev, 8, &pBuffer);
  1057. pBuffer[0] = __Permedia2TagDitherMode;
  1058. pBuffer[1] = 0;
  1059. pBuffer[2] = __Permedia2TagTextureAddressMode;
  1060. pBuffer[3] = __PERMEDIA_DISABLE;
  1061. pBuffer[4] = __Permedia2TagTextureColorMode;
  1062. pBuffer[5] = __PERMEDIA_DISABLE;
  1063. pBuffer[6] = __Permedia2TagTextureReadMode;
  1064. pBuffer[7] = __PERMEDIA_DISABLE;
  1065. pBuffer += 8;
  1066. InputBufferCommit(ppdev, pBuffer);
  1067. }