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.

1527 lines
59 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * **************************
  4. * * DirectDraw SAMPLE CODE *
  5. * **************************
  6. *
  7. * Module Name: ddblt.c
  8. *
  9. * Content: DirectDraw Blt callback implementation for blts and clears
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "glint.h"
  15. #include "tag.h"
  16. #include "dma.h"
  17. //-----------------------------------------------------------------------------
  18. //
  19. // _DD_BLT_P3Clear
  20. //
  21. //-----------------------------------------------------------------------------
  22. VOID
  23. _DD_BLT_P3Clear(
  24. P3_THUNKEDDATA* pThisDisplay,
  25. RECTL *rDest,
  26. DWORD ClearValue,
  27. BOOL bDisableFastFill,
  28. BOOL bIsZBuffer,
  29. FLATPTR pDestfpVidMem,
  30. DWORD dwDestPatchMode,
  31. DWORD dwDestPixelPitch,
  32. DWORD dwDestBitDepth
  33. )
  34. {
  35. DWORD renderData, pixelSize, pixelScale;
  36. BOOL bFastFillOperation = TRUE;
  37. DWORD dwOperation;
  38. P3_DMA_DEFS();
  39. P3_DMA_GET_BUFFER_ENTRIES(18);
  40. if(bDisableFastFill)
  41. {
  42. bFastFillOperation = FALSE;
  43. }
  44. switch(dwDestBitDepth)
  45. {
  46. case 16:
  47. ClearValue &= 0xFFFF;
  48. ClearValue |= ClearValue << 16;
  49. pixelSize = 1;
  50. pixelScale = 1;
  51. break;
  52. case 8:
  53. ClearValue &= 0xFF;
  54. ClearValue |= ClearValue << 8;
  55. ClearValue |= ClearValue << 16;
  56. pixelSize = 2;
  57. pixelScale = 1;
  58. break;
  59. case 32:
  60. if( bFastFillOperation )
  61. {
  62. // Do the operation as 16 bit due to FBWrite bug
  63. pixelSize = 1;
  64. pixelScale = 2;
  65. }
  66. else
  67. {
  68. pixelSize = 0;
  69. pixelScale = 1;
  70. }
  71. break;
  72. default:
  73. DISPDBG((ERRLVL,"ERROR: Invalid depth for surface during clear!"));
  74. // Treat as a 16bpp just as fallback though this should never happen
  75. ClearValue &= 0xFFFF;
  76. ClearValue |= ClearValue << 16;
  77. pixelSize = 1;
  78. pixelScale = 1;
  79. break;
  80. }
  81. SEND_P3_DATA(PixelSize, pixelSize );
  82. SEND_P3_DATA(FBWriteBufferAddr0,
  83. (DWORD)(pDestfpVidMem -
  84. pThisDisplay->dwScreenFlatAddr) );
  85. SEND_P3_DATA(FBWriteBufferWidth0,
  86. pixelScale * dwDestPixelPitch );
  87. SEND_P3_DATA(FBWriteBufferOffset0,
  88. (rDest->top << 16) | pixelScale * ((rDest->left & 0xFFFF)));
  89. SEND_P3_DATA(FBDestReadBufferAddr0,
  90. (DWORD)(pDestfpVidMem -
  91. pThisDisplay->dwScreenFlatAddr) );
  92. SEND_P3_DATA(FBDestReadBufferWidth0,
  93. pixelScale * dwDestPixelPitch );
  94. SEND_P3_DATA(FBDestReadBufferOffset0,
  95. (rDest->top << 16) | pixelScale * ((rDest->left & 0xFFFF)));
  96. SEND_P3_DATA(RectanglePosition, 0);
  97. dwOperation = P3RX_RENDER2D_OPERATION( P3RX_RENDER2D_OPERATION_NORMAL );
  98. SEND_P3_DATA(FBWriteMode,
  99. P3RX_FBWRITEMODE_WRITEENABLE(__PERMEDIA_ENABLE) |
  100. P3RX_FBWRITEMODE_LAYOUT0(dwDestPatchMode));
  101. P3_DMA_COMMIT_BUFFER();
  102. P3_DMA_GET_BUFFER_ENTRIES(18);
  103. if( bFastFillOperation )
  104. {
  105. DWORD shift = 0;
  106. SEND_P3_DATA(FBBlockColor, ClearValue);
  107. renderData = P3RX_RENDER2D_WIDTH( pixelScale * (( rDest->right - rDest->left ) & 0xfff ))
  108. | P3RX_RENDER2D_HEIGHT((( rDest->bottom - rDest->top ) & 0xfff ) >> shift )
  109. | P3RX_RENDER2D_SPANOPERATION( P3RX_RENDER2D_SPAN_CONSTANT )
  110. | P3RX_RENDER2D_INCREASINGX( __PERMEDIA_ENABLE )
  111. | P3RX_RENDER2D_INCREASINGY( __PERMEDIA_ENABLE )
  112. | dwOperation;
  113. SEND_P3_DATA(Render2D, renderData);
  114. }
  115. else
  116. {
  117. SEND_P3_DATA(ConstantColor, ClearValue);
  118. SEND_P3_DATA(DitherMode, __PERMEDIA_DISABLE);
  119. SEND_P3_DATA(ColorDDAMode,
  120. P3RX_COLORDDA_ENABLE(__PERMEDIA_ENABLE) |
  121. P3RX_COLORDDA_SHADING(P3RX_COLORDDA_FLATSHADE));
  122. renderData = P3RX_RENDER2D_WIDTH(( rDest->right - rDest->left ) & 0xfff )
  123. | P3RX_RENDER2D_HEIGHT(0)
  124. | P3RX_RENDER2D_SPANOPERATION( P3RX_RENDER2D_SPAN_CONSTANT )
  125. | P3RX_RENDER2D_INCREASINGX( __PERMEDIA_ENABLE )
  126. | P3RX_RENDER2D_INCREASINGY( __PERMEDIA_ENABLE );
  127. SEND_P3_DATA(Render2D, renderData);
  128. SEND_P3_DATA(Count, rDest->bottom - rDest->top );
  129. SEND_P3_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE);
  130. SEND_P3_DATA(ColorDDAMode, __PERMEDIA_DISABLE);
  131. }
  132. P3_DMA_COMMIT_BUFFER();
  133. } // _DD_BLT_P3Clear
  134. //-----------------------------------------------------------------------------
  135. //
  136. // _DD_BLT_P3ClearDD
  137. //
  138. // Does a DDraw surface clear
  139. //
  140. //-----------------------------------------------------------------------------
  141. VOID
  142. _DD_BLT_P3ClearDD(
  143. P3_THUNKEDDATA* pThisDisplay,
  144. LPDDRAWI_DDRAWSURFACE_LCL pDest,
  145. P3_SURF_FORMAT* pFormatDest,
  146. RECTL *rDest,
  147. DWORD ClearValue,
  148. BOOL bDisableFastFill,
  149. BOOL bIsZBuffer
  150. )
  151. {
  152. _DD_BLT_P3Clear(pThisDisplay,
  153. rDest,
  154. ClearValue,
  155. bDisableFastFill,
  156. bIsZBuffer,
  157. pDest->lpGbl->fpVidMem,
  158. P3RX_LAYOUT_LINEAR,
  159. DDSurf_GetPixelPitch(pDest),
  160. DDSurf_BitDepth(pDest)
  161. );
  162. } // _DD_BLT_P3ClearDD
  163. #if DX7_TEXMANAGEMENT
  164. //-----------------------------------------------------------------------------
  165. //
  166. // _DD_BLT_P3ClearManagedSurf
  167. //
  168. // Does a clear of a managed surface. Supports all color depths
  169. //
  170. // PixelSize-----surface color depth
  171. // rDest---------rectangle for colorfill in dest. surface
  172. // fpVidMem------pointer to fill
  173. // lPitch--------Surface Pitch
  174. // dwColor-------color for fill
  175. //
  176. //-----------------------------------------------------------------------------
  177. VOID
  178. _DD_BLT_P3ClearManagedSurf(DWORD PixelSize,
  179. RECTL *rDest,
  180. FLATPTR fpVidMem,
  181. LONG lPitch,
  182. DWORD dwColor)
  183. {
  184. BYTE* pDestStart;
  185. LONG i;
  186. LONG lByteWidth = rDest->right - rDest->left;
  187. LONG lHeight = rDest->bottom - rDest->top;
  188. // Calculate the start pointer for the dest
  189. pDestStart = (BYTE*)(fpVidMem + (rDest->top * lPitch));
  190. // Clear depending on depth
  191. switch (PixelSize)
  192. {
  193. case __GLINT_8BITPIXEL:
  194. pDestStart += rDest->left;
  195. while (--lHeight >= 0)
  196. {
  197. for (i = 0; i < lByteWidth ; i++)
  198. pDestStart[i] = (BYTE)dwColor;
  199. pDestStart += lPitch;
  200. }
  201. break;
  202. case __GLINT_16BITPIXEL:
  203. pDestStart += rDest->left*2;
  204. while (--lHeight >= 0)
  205. {
  206. LPWORD lpWord=(LPWORD)pDestStart;
  207. for (i = 0; i < lByteWidth ; i++)
  208. lpWord[i] = (WORD)dwColor;
  209. pDestStart += lPitch;
  210. }
  211. break;
  212. case __GLINT_24BITPIXEL:
  213. dwColor &= 0xFFFFFF;
  214. dwColor |= ((dwColor & 0xFF) << 24);
  215. default: // 32 bits!
  216. pDestStart += rDest->left*4;
  217. while (--lHeight >= 0)
  218. {
  219. LPDWORD lpDWord = (LPDWORD)pDestStart;
  220. for (i = 0; i < lByteWidth; i++)
  221. lpDWord[i] = (WORD)dwColor;
  222. pDestStart += lPitch;
  223. }
  224. break;
  225. }
  226. } // _DD_BLT_P3ClearManagedSurf
  227. #endif // DX7_TEXMANAGEMENT
  228. #if DX8_MULTISAMPLING || DX7_ANTIALIAS
  229. //-----------------------------------------------------------------------------
  230. //
  231. // _DD_BLT_P3Clear_AA
  232. //
  233. //-----------------------------------------------------------------------------
  234. VOID _DD_BLT_P3Clear_AA(
  235. P3_THUNKEDDATA* pThisDisplay,
  236. RECTL *rDest,
  237. DWORD dwSurfaceOffset,
  238. DWORD ClearValue,
  239. BOOL bDisableFastFill,
  240. DWORD dwDestPatchMode,
  241. DWORD dwDestPixelPitch,
  242. DWORD dwDestBitDepth,
  243. DDSCAPS DestDdsCaps)
  244. {
  245. DWORD renderData, pixelSize, pixelScale;
  246. BOOL bFastFillOperation = TRUE;
  247. P3_DMA_DEFS();
  248. P3_DMA_GET_BUFFER();
  249. P3_ENSURE_DX_SPACE(32);
  250. WAIT_FIFO(32);
  251. if (bDisableFastFill)
  252. {
  253. bFastFillOperation = FALSE;
  254. }
  255. switch(dwDestBitDepth)
  256. {
  257. case 16:
  258. ClearValue &= 0xFFFF;
  259. ClearValue |= ClearValue << 16;
  260. pixelSize = 1;
  261. pixelScale = 1;
  262. break;
  263. case 8:
  264. ClearValue &= 0xFF;
  265. ClearValue |= ClearValue << 8;
  266. ClearValue |= ClearValue << 16;
  267. pixelSize = 2;
  268. pixelScale = 1;
  269. break;
  270. case 32:
  271. // 32 bit Z-buffer can be used for 16 bit antialiased render buffer
  272. if( bFastFillOperation )
  273. {
  274. // Do the operation as 16 bit due to FBWrite bug
  275. pixelSize = 1;
  276. pixelScale = 2;
  277. }
  278. else
  279. {
  280. pixelSize = 0;
  281. pixelScale = 1;
  282. }
  283. break;
  284. default:
  285. DISPDBG((ERRLVL,"ERROR: Invalid depth for surface during clear!"));
  286. // Treat as a 16bpp just as fallback
  287. ClearValue &= 0xFFFF;
  288. ClearValue |= ClearValue << 16;
  289. pixelSize = 1;
  290. pixelScale = 1;
  291. break;
  292. }
  293. SEND_P3_DATA(PixelSize, pixelSize);
  294. SEND_P3_DATA(FBWriteBufferAddr0, dwSurfaceOffset);
  295. SEND_P3_DATA(FBWriteBufferWidth0, pixelScale * (dwDestPixelPitch * 2));
  296. SEND_P3_DATA(FBWriteBufferOffset0, (rDest->top << 16) |
  297. pixelScale * ((rDest->left & 0xFFFF)));
  298. SEND_P3_DATA(FBDestReadBufferAddr0, dwSurfaceOffset );
  299. SEND_P3_DATA(FBDestReadBufferWidth0, pixelScale * dwDestPixelPitch );
  300. SEND_P3_DATA(FBDestReadBufferOffset0, (rDest->top << 16) |
  301. pixelScale * ((rDest->left & 0xFFFF)));
  302. SEND_P3_DATA(RectanglePosition, 0);
  303. SEND_P3_DATA(FBWriteMode, P3RX_FBWRITEMODE_WRITEENABLE(__PERMEDIA_ENABLE) |
  304. P3RX_FBWRITEMODE_LAYOUT0(dwDestPatchMode));
  305. if( bFastFillOperation )
  306. {
  307. SEND_P3_DATA(FBBlockColor, ClearValue);
  308. renderData = P3RX_RENDER2D_WIDTH( pixelScale * (( rDest->right - rDest->left ) & 0xfff ))
  309. | P3RX_RENDER2D_HEIGHT(( rDest->bottom - rDest->top ) & 0xfff )
  310. | P3RX_RENDER2D_INCREASINGX( __PERMEDIA_ENABLE )
  311. | P3RX_RENDER2D_INCREASINGY( __PERMEDIA_ENABLE );
  312. SEND_P3_DATA(Render2D, renderData);
  313. }
  314. else
  315. {
  316. SEND_P3_DATA(ConstantColor, ClearValue);
  317. SEND_P3_DATA(DitherMode, __PERMEDIA_DISABLE);
  318. SEND_P3_DATA(ColorDDAMode, P3RX_COLORDDA_ENABLE(__PERMEDIA_ENABLE) |
  319. P3RX_COLORDDA_SHADING(P3RX_COLORDDA_FLATSHADE));
  320. renderData = P3RX_RENDER2D_WIDTH(( rDest->right - rDest->left ) & 0xfff )
  321. | P3RX_RENDER2D_HEIGHT(0)
  322. | P3RX_RENDER2D_INCREASINGX( __PERMEDIA_ENABLE )
  323. | P3RX_RENDER2D_SPANOPERATION( P3RX_RENDER2D_SPAN_CONSTANT )
  324. | P3RX_RENDER2D_INCREASINGY( __PERMEDIA_ENABLE );
  325. SEND_P3_DATA(Render2D, renderData);
  326. SEND_P3_DATA(Count, rDest->bottom - rDest->top );
  327. SEND_P3_DATA(Render, __RENDER_TRAPEZOID_PRIMITIVE);
  328. SEND_P3_DATA(ColorDDAMode, __PERMEDIA_DISABLE);
  329. }
  330. P3_DMA_COMMIT_BUFFER();
  331. } // _DD_BLT_P3Clear_AA
  332. //-----------------------------------------------------------------------------
  333. //
  334. // _DD_BLT_P3Clear_AA_DD
  335. //
  336. //-----------------------------------------------------------------------------
  337. VOID _DD_BLT_P3Clear_AA_DD(
  338. P3_THUNKEDDATA* pThisDisplay,
  339. LPDDRAWI_DDRAWSURFACE_LCL pDest,
  340. P3_SURF_FORMAT* pFormatDest,
  341. RECTL *rDest,
  342. DWORD dwSurfaceOffset,
  343. DWORD ClearValue,
  344. BOOL bDisableFastFill)
  345. {
  346. _DD_BLT_P3Clear_AA(pThisDisplay,
  347. rDest,
  348. dwSurfaceOffset,
  349. ClearValue,
  350. bDisableFastFill,
  351. P3RX_LAYOUT_LINEAR,
  352. DDSurf_GetPixelPitch(pDest),
  353. DDSurf_BitDepth(pDest),
  354. pDest->ddsCaps
  355. );
  356. } // _DD_BLT_P3Clear_AA_DD
  357. #endif // DX8_MULTISAMPLING || DX7_ANTIALIAS
  358. #if DX7_TEXMANAGEMENT
  359. //-----------------------------------------------------------------------------
  360. //
  361. // _DD_BLT_SysMemToSysMemCopy
  362. //
  363. // Does a copy from System memory to System memory (either from or to an
  364. // AGP surface, or any other system memory surface)
  365. //
  366. //-----------------------------------------------------------------------------
  367. VOID
  368. _DD_BLT_SysMemToSysMemCopy(FLATPTR fpSrcVidMem,
  369. LONG lSrcPitch,
  370. DWORD dwSrcBitCount,
  371. FLATPTR fpDstVidMem,
  372. LONG lDstPitch,
  373. DWORD dwDstBitCount,
  374. RECTL* rSource,
  375. RECTL* rDest)
  376. {
  377. BYTE* pSourceStart;
  378. BYTE* pDestStart;
  379. BYTE pixSource;
  380. BYTE* pNewDest;
  381. BYTE* pNewSource;
  382. // Computing these from the smaller of Dest and Src as it is safer
  383. // (we might touch invalid memory if for any weird reason we're
  384. // asked to do a stretch blt here!)
  385. LONG lByteWidth = min(rDest->right - rDest->left,
  386. rSource->right - rSource->left);
  387. LONG lHeight = min(rDest->bottom - rDest->top,
  388. rSource->bottom - rSource->top);
  389. if (0 == fpSrcVidMem || 0 == fpDstVidMem)
  390. {
  391. DISPDBG((WRNLVL, "DDraw:_DD_BLT_SysMemToSysMemCopy "
  392. "unexpected 0 fpVidMem"));
  393. return;
  394. }
  395. // Calculate the start pointer for the source and the dest
  396. pSourceStart = (BYTE*)(fpSrcVidMem + (rSource->top * lSrcPitch));
  397. pDestStart = (BYTE*)(fpDstVidMem + (rDest->top * lDstPitch));
  398. // The simple 8, 16 or 32 bit copy
  399. pSourceStart += rSource->left * (dwSrcBitCount >> 3);
  400. pDestStart += rDest->left * (dwDstBitCount >> 3);
  401. lByteWidth *= (dwSrcBitCount >> 3);
  402. _try
  403. {
  404. while (--lHeight >= 0)
  405. {
  406. memcpy(pDestStart, pSourceStart, lByteWidth);
  407. pDestStart += lDstPitch;
  408. pSourceStart += lSrcPitch;
  409. };
  410. }
  411. __except(EXCEPTION_EXECUTE_HANDLER)
  412. {
  413. // Perm3 driver doesn't need to do anything special
  414. DISPDBG((ERRLVL, "Perm3 caused exception at line %u of file %s",
  415. __LINE__,__FILE__));
  416. }
  417. } // _DD_BLT_SysMemToSysMemCopy
  418. #endif // DX7_TEXMANAGEMENT
  419. //-----------------------------------------------------------------------------
  420. //
  421. // _DD_BLT_FixRectlOrigin
  422. //
  423. // Fix blt coords in case some are negative. If the area is completly NULL
  424. // (coordinate-wise) then return FALSE, signaling there is nothing to be
  425. // blitted.
  426. //
  427. //-----------------------------------------------------------------------------
  428. BOOL _DD_BLT_FixRectlOrigin(char *pszPlace, RECTL *rSrc, RECTL *rDest)
  429. {
  430. if ((rSrc->top < 0 && rSrc->bottom < 0) ||
  431. (rSrc->left < 0 && rSrc->right < 0))
  432. {
  433. // There is nothing to be blitted
  434. return FALSE;
  435. }
  436. if (rSrc->top < 0 ||
  437. rSrc->left < 0 ||
  438. rDest->top < 0 ||
  439. rDest->left < 0)
  440. {
  441. DISPDBG((DBGLVL, "Dodgy blt coords:"));
  442. DISPDBG((DBGLVL, " src([%d, %d], [%d, %d]",
  443. rSrc->left, rSrc->top,
  444. rSrc->right, rSrc->bottom));
  445. DISPDBG((DBGLVL, " dst([%d, %d], [%d, %d]",
  446. rDest->left, rDest->top,
  447. rDest->right, rDest->bottom));
  448. }
  449. if (rSrc->top < 0)
  450. {
  451. rDest->top -= rSrc->top;
  452. rSrc->top = 0;
  453. }
  454. if (rSrc->left < 0)
  455. {
  456. rDest->left -= rSrc->left;
  457. rSrc->left = 0;
  458. }
  459. DISPDBG((DBGLVL, "%s from (%d, %d) to (%d,%d) (%d, %d)",
  460. pszPlace,
  461. rSrc->left, rSrc->top,
  462. rDest->left, rDest->top,
  463. rDest->right, rDest->bottom));
  464. return TRUE; // Blt is valid
  465. } // _DD_BLT_FixRectlOrigin
  466. //-----------------------------------------------------------------------------
  467. //
  468. // _DD_BLT_GetBltDirection
  469. //
  470. // Determine the direction of the blt
  471. // ==1 => increasing-x && increasing-y
  472. // ==0 => decreasing-x && decreasing-y
  473. //
  474. // Also, the boolean pbBlocking determines if there is a potential clash
  475. // because of common scan lines.
  476. //
  477. //-----------------------------------------------------------------------------
  478. DWORD
  479. _DD_BLT_GetBltDirection(
  480. FLATPTR pSrcfpVidMem,
  481. FLATPTR pDestfpVidMem,
  482. RECTL *rSrc,
  483. RECTL *rDest,
  484. BOOL *pbBlocking)
  485. {
  486. DWORD dwRenderDirection;
  487. *pbBlocking = FALSE;
  488. if( pDestfpVidMem != pSrcfpVidMem )
  489. {
  490. // Not the same surface, so always render downwards.
  491. dwRenderDirection = 1;
  492. }
  493. else
  494. {
  495. // Same surface - must choose render direction.
  496. if(rSrc->top < rDest->top)
  497. {
  498. dwRenderDirection = 0;
  499. }
  500. else if(rSrc->top > rDest->top)
  501. {
  502. dwRenderDirection = 1;
  503. }
  504. else // y1 == y2
  505. {
  506. if(rSrc->left < rDest->left)
  507. {
  508. dwRenderDirection = 0;
  509. }
  510. else
  511. {
  512. dwRenderDirection = 1;
  513. }
  514. // It was found that this condition doesn't guarantee clean blits
  515. // therefore we need to do a blocking 2D blit
  516. *pbBlocking = TRUE;
  517. }
  518. }
  519. return dwRenderDirection;
  520. } // _DD_BLT_GetBltDirection
  521. //-----------------------------------------------------------------------------
  522. //
  523. // _DD_BLT_P3CopyBlt
  524. //
  525. // Perform a Copy blt between the specified surfaces.
  526. //
  527. //-----------------------------------------------------------------------------
  528. VOID _DD_BLT_P3CopyBlt(
  529. P3_THUNKEDDATA* pThisDisplay,
  530. FLATPTR pSrcfpVidMem,
  531. FLATPTR pDestfpVidMem,
  532. DWORD dwSrcChipPatchMode,
  533. DWORD dwDestChipPatchMode,
  534. DWORD dwSrcPitch,
  535. DWORD dwDestPitch,
  536. DWORD dwSrcOffset,
  537. DWORD dwDestOffset,
  538. DWORD dwDestPixelSize,
  539. RECTL *rSrc,
  540. RECTL *rDest)
  541. {
  542. DWORD renderData;
  543. LONG rSrctop, rSrcleft, rDesttop, rDestleft;
  544. DWORD dwSourceOffset;
  545. BOOL bBlocking;
  546. DWORD dwRenderDirection;
  547. P3_DMA_DEFS();
  548. // Beacuse of a bug in RL we sometimes have to fiddle with these values
  549. rSrctop = rSrc->top;
  550. rSrcleft = rSrc->left;
  551. rDesttop = rDest->top;
  552. rDestleft = rDest->left;
  553. // Fix coords origin
  554. if (!_DD_BLT_FixRectlOrigin("_DD_BLT_P3CopyBlt", rSrc, rDest))
  555. {
  556. // Nothing to be blitted
  557. return;
  558. }
  559. // Determine the direction of the blt
  560. dwRenderDirection = _DD_BLT_GetBltDirection(pSrcfpVidMem,
  561. pDestfpVidMem,
  562. rSrc,
  563. rDest,
  564. &bBlocking);
  565. P3_DMA_GET_BUFFER();
  566. P3_ENSURE_DX_SPACE(40);
  567. WAIT_FIFO(20);
  568. SEND_P3_DATA(PixelSize, (2 - dwDestPixelSize));
  569. SEND_P3_DATA(FBWriteBufferAddr0, dwDestOffset);
  570. SEND_P3_DATA(FBWriteBufferWidth0, dwDestPitch);
  571. SEND_P3_DATA(FBWriteBufferOffset0, 0);
  572. SEND_P3_DATA(FBSourceReadBufferAddr, dwSrcOffset);
  573. SEND_P3_DATA(FBSourceReadBufferWidth, dwSrcPitch);
  574. dwSourceOffset = (( rSrc->top - rDest->top ) << 16 ) |
  575. (( rSrc->left - rDest->left ) & 0xffff );
  576. SEND_P3_DATA(FBSourceReadBufferOffset, dwSourceOffset);
  577. SEND_P3_DATA(FBDestReadMode,
  578. P3RX_FBDESTREAD_READENABLE(__PERMEDIA_DISABLE));
  579. SEND_P3_DATA(FBSourceReadMode,
  580. P3RX_FBSOURCEREAD_READENABLE(__PERMEDIA_ENABLE) |
  581. P3RX_FBSOURCEREAD_LAYOUT(dwSrcChipPatchMode) |
  582. P3RX_FBSOURCEREAD_BLOCKING( bBlocking ));
  583. SEND_P3_DATA(FBWriteMode,
  584. P3RX_FBWRITEMODE_WRITEENABLE(__PERMEDIA_ENABLE) |
  585. P3RX_FBWRITEMODE_LAYOUT0(dwDestChipPatchMode));
  586. WAIT_FIFO(20);
  587. SEND_P3_DATA(RectanglePosition, P3RX_RECTANGLEPOSITION_Y(rDest->top) |
  588. P3RX_RECTANGLEPOSITION_X(rDest->left));
  589. renderData = P3RX_RENDER2D_WIDTH(( rDest->right - rDest->left ) & 0xfff )
  590. | P3RX_RENDER2D_HEIGHT(( rDest->bottom - rDest->top ) & 0xfff )
  591. | P3RX_RENDER2D_FBREADSOURCEENABLE(__PERMEDIA_ENABLE)
  592. | P3RX_RENDER2D_SPANOPERATION( P3RX_RENDER2D_SPAN_VARIABLE )
  593. | P3RX_RENDER2D_INCREASINGX( dwRenderDirection )
  594. | P3RX_RENDER2D_INCREASINGY( dwRenderDirection );
  595. SEND_P3_DATA(Render2D, renderData);
  596. // Put back the values if we changed them.
  597. rSrc->top = rSrctop;
  598. rSrc->left = rSrcleft;
  599. rDest->top = rDesttop;
  600. rDest->left = rDestleft;
  601. P3_DMA_COMMIT_BUFFER();
  602. } // _DD_BLT_P3CopyBlt
  603. //-----------------------------------------------------------------------------
  604. //
  605. // _DD_BLT_P3CopyBltDD
  606. //
  607. // Perform a Copy blt between the specified Ddraw surfaces.
  608. //
  609. //-----------------------------------------------------------------------------
  610. VOID _DD_BLT_P3CopyBltDD(
  611. P3_THUNKEDDATA* pThisDisplay,
  612. LPDDRAWI_DDRAWSURFACE_LCL pSource,
  613. LPDDRAWI_DDRAWSURFACE_LCL pDest,
  614. P3_SURF_FORMAT* pFormatSource,
  615. P3_SURF_FORMAT* pFormatDest,
  616. RECTL *rSrc,
  617. RECTL *rDest)
  618. {
  619. _DD_BLT_P3CopyBlt(pThisDisplay,
  620. pSource->lpGbl->fpVidMem,
  621. pDest->lpGbl->fpVidMem,
  622. P3RX_LAYOUT_LINEAR, // src
  623. P3RX_LAYOUT_LINEAR, // dst
  624. DDSurf_GetPixelPitch(pSource),
  625. DDSurf_GetPixelPitch(pDest),
  626. DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pSource),
  627. DDSurf_SurfaceOffsetFromMemoryBase(pThisDisplay, pDest),
  628. DDSurf_GetChipPixelSize(pDest),
  629. rSrc,
  630. rDest);
  631. } // _DD_BLT_P3CopyBltDD
  632. //-----------------------------------------------------------------------------
  633. //
  634. // DdBlt
  635. //
  636. // Performs a bit-block transfer.
  637. //
  638. // DdBlt can be optionally implemented in DirectDraw drivers.
  639. //
  640. // Before performing the bit block transfer, the driver should ensure that a
  641. // flip involving the destination surface is not in progress. If the destination
  642. // surface is involved in a flip, the driver should set ddRVal to
  643. // DDERR_WASSTILLDRAWING and return DDHAL_DRIVER_HANDLED.
  644. //
  645. // The driver should check dwFlags to determine the type of blt operation to
  646. // perform. The driver should not check for flags that are undocumented.
  647. //
  648. // Parameters
  649. //
  650. // lpBlt
  651. // Points to the DD_BLTDATA structure that contains the information
  652. // required for the driver to perform the blt.
  653. //
  654. // .lpDD
  655. // Points to a DD_DIRECTDRAW_GLOBAL structure that describes the
  656. // DirectDraw object.
  657. // .lpDDDestSurface
  658. // Points to the DD_SURFACE_LOCAL structure that describes the
  659. // surface on which to blt.
  660. // .rDest
  661. // Points to a RECTL structure that specifies the upper left and
  662. // lower right points of a rectangle on the destination surface.
  663. // These points define the area in which the blt should occur and
  664. // its position on the destination surface
  665. // .lpDDSrcSurface
  666. // Points to a DD_SURFACE_LOCAL structure that describes the
  667. // source surface.
  668. // .rSrc
  669. // Points to a RECTL structure that specifies the upper left and
  670. // lower right points of a rectangle on the source surface. These
  671. // points define the area of the source blt data and its position
  672. // on the source surface.
  673. // .dwFlags
  674. // Specify the type of blt operation to perform and which
  675. // associated structure members have valid data that the driver
  676. // should use. This member is a bit-wise OR of any of the following
  677. // flags:
  678. //
  679. // DDBLT_AFLAGS
  680. // This flag is not yet used as of DirectX� 7.0. Indicates to
  681. // the driver that the dwAFlags and ddrgbaScaleFactors members
  682. // in this structure are valid. This flag is always set if the
  683. // DD_BLTDATA structure is passed to the driver from the
  684. // DdAlphaBlt callback. Otherwise this flag is zero. If this
  685. // flag is set, the DDBLT_ROTATIONANGLE and DDBLT_ROP flags
  686. // will be zero.
  687. // DDBLT_ASYNC
  688. // Do this blt asynchronously through the FIFO in the order
  689. // received. If no room exists in the hardware FIFO, the driver
  690. // should fail the call and return immediately.
  691. // DDBLT_COLORFILL
  692. // Use the dwFillColor member in the DDBLTFX structure as the
  693. // RGB color with which to fill the destination rectangle on
  694. // the destination surface.
  695. // DDBLT_DDFX
  696. // Use the dwDDFX member in the DDBLTFX structure to determine
  697. // the effects to use for the blt.
  698. // DDBLT_DDROPS
  699. // This is reserved for system use and should be ignored by the
  700. // driver. The driver should also ignore the dwDDROPS member of
  701. // the DDBLTFX structure.
  702. // DDBLT_KEYDESTOVERRIDE
  703. // Use the dckDestColorkey member in the DDBLTFX structure as
  704. // the color key for the destination surface. If an override
  705. // is not being set, then dckDestColorkey does not contain the
  706. // color key. The driver should test the surface itself.
  707. // DDBLT_KEYSRCOVERRIDE
  708. // Use the dckSrcColorkey member in the DDBLTFX structure as
  709. // the color key for the source surface. If an override is
  710. // not being set, then dckDestColorkey does not contain the
  711. // color key. The driver should test the surface itself.
  712. // DDBLT_ROP
  713. // Use the dwROP member in the DDBLTFX structure for the
  714. // raster operation for this blt. Currently, the only ROP
  715. // passed to the driver is SRCCOPY. This ROP is the same as
  716. // defined in the Win32� API. See the Platform SDK for details.
  717. // DDBLT_ROTATIONANGLE
  718. // This is not supported on Windows 2000 and should be ignored
  719. // by the driver.
  720. //
  721. // .dwROPFlags
  722. // This is unused on Windows 2000 and should be ignored by the
  723. // driver.
  724. // .bltFX
  725. // Specifies a DDBLTFX structure that contains override
  726. // information for more complex blt operations. For example, the
  727. // dwFillColor field is used for solid color fills, and the
  728. // ddckSrcColorKey and ddckDestColorKey fields are used for
  729. // color key blts. The driver can determine which members of
  730. // bltFX contain valid data by looking at the dwFlags member of
  731. // the DD_BLTDATA structure. Note that the DDBLTFX_NOTEARING,
  732. // DDBLTFX_MIRRORLEFTRIGHT, and DDBLTFX_MIRRORUPDOWN flags are
  733. // unsupported on Windows 2000 and will never be passed to the
  734. // driver. See the Platform SDK for DDBLTFX documentation.
  735. // .ddRVal
  736. // This is the location in which the driver writes the return
  737. // value of the DdBlt callback. A return code of DD_OK indicates
  738. // success.
  739. // .Blt
  740. // This is unused on Windows 2000.
  741. // .IsClipped
  742. // Indicates whether this is a clipped blt. On Windows 2000,
  743. // this member is always FALSE, indicating that the blt is
  744. // unclipped.
  745. // .rOrigDest
  746. // This member is unused for Windows 2000. Specifies a RECTL
  747. // structure that defines the unclipped destination rectangle.
  748. // This member is valid only if IsClipped is TRUE.
  749. // .rOrigSrc
  750. // This member is unused for Windows 2000. Specifies a RECTL
  751. // structure that defines the unclipped source rectangle. This
  752. // member is valid only if IsClipped is TRUE.
  753. // .dwRectCnt
  754. // This member is unused for Windows 2000. Specifies the number
  755. // of destination rectangles to which prDestRects points. This
  756. // member is valid only if IsClipped is TRUE.
  757. // .prDestRects
  758. // This member is unused for Windows 2000. Points to an array of
  759. // RECTL structures that describe of destination rectangles. This
  760. // member is valid only if IsClipped is TRUE.
  761. // .dwAFlags
  762. // This member is only valid if the DDBLT_AFLAGS flag is set in
  763. // the dwFlags member of this structure. This member specifies
  764. // operation flags used only by the DdAlphaBlt callback (which
  765. // is not yet implemented as of DirectX 7.0). This member is a
  766. // bit-wise OR of any of the following flags:
  767. //
  768. // DDABLT_BILINEARFLITER
  769. // Enable bilinear filtering of the source pixels during a
  770. // stretch blit. By default, no filtering is performed.
  771. // Instead, a nearest neighbor source pixel is copied to a
  772. // destination pixel
  773. // DDABLT_NOBLEND
  774. // Write the source pixel values to the destination surface
  775. // without blending. The pixels are converted from the source
  776. // pixel format to the destination format, but no color
  777. // keying, alpha blending, or RGBA scaling is performed. In
  778. // the case of a fill operation (where the lpDDSrcSurface
  779. // member is NULL), the lpDDRGBAScaleFactors member of this
  780. // structure points to the source alpha and color components
  781. // that are to be converted to the destination pixel format
  782. // and are used to fill the destination. A blit operation is
  783. // performed if a valid source surface is specified, but in
  784. // this case, lpDDRGBAScaleFactors must be NULL or the call
  785. // will fail. This flag cannot be used in conjunction with
  786. // the DDBLT_KEYSRC and DDBLT_KEYDEST flags.
  787. // DDABLT_SRCOVERDEST
  788. // If set, this flag indicates that the operation originated
  789. // from the application's AlphaBlt method. If the call was
  790. // originated by the application's Blt method, this flag is
  791. // not set. Drivers that have a unified DdBlt and DdAlphaBlt
  792. // callback can use this flag to distinguish between the two
  793. // application method calls.
  794. //
  795. // .ddrgbaScaleFactors
  796. // This member is only valid if the DDBLT_AFLAGS flag is set in
  797. // the dwFlags member of this structure. DDARGB structure that
  798. // contains the RGBA-scaling factors used to scale the color and
  799. // alpha components of each source pixel before it is composited
  800. // to the destination surface.
  801. //
  802. //-----------------------------------------------------------------------------
  803. DWORD CALLBACK
  804. DdBlt(
  805. LPDDHAL_BLTDATA lpBlt )
  806. {
  807. RECTL rSrc;
  808. RECTL rDest;
  809. DWORD dwFlags;
  810. BYTE rop;
  811. LPDDRAWI_DDRAWSURFACE_LCL pSrcLcl;
  812. LPDDRAWI_DDRAWSURFACE_LCL pDestLcl;
  813. LPDDRAWI_DDRAWSURFACE_GBL pSrcGbl;
  814. LPDDRAWI_DDRAWSURFACE_GBL pDestGbl;
  815. P3_SURF_FORMAT* pFormatSource;
  816. P3_SURF_FORMAT* pFormatDest;
  817. P3_THUNKEDDATA* pThisDisplay;
  818. HRESULT ddrval = DD_OK;
  819. BOOL bOverlapStretch = FALSE;
  820. DBG_CB_ENTRY(DdBlt);
  821. pDestLcl = lpBlt->lpDDDestSurface;
  822. pSrcLcl = lpBlt->lpDDSrcSurface;
  823. GET_THUNKEDDATA(pThisDisplay, lpBlt->lpDD);
  824. VALIDATE_MODE_AND_STATE(pThisDisplay);
  825. pDestGbl = pDestLcl->lpGbl;
  826. pFormatDest = _DD_SUR_GetSurfaceFormat(pDestLcl);
  827. DISPDBG((DBGLVL, "Dest Surface:"));
  828. DBGDUMP_DDRAWSURFACE_LCL(DBGLVL, pDestLcl);
  829. dwFlags = lpBlt->dwFlags;
  830. STOP_SOFTWARE_CURSOR(pThisDisplay);
  831. ddrval = _DX_QueryFlipStatus(pThisDisplay, pDestGbl->fpVidMem, TRUE);
  832. if( FAILED( ddrval ) )
  833. {
  834. lpBlt->ddRVal = ddrval;
  835. START_SOFTWARE_CURSOR(pThisDisplay);
  836. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  837. return DDHAL_DRIVER_HANDLED;
  838. }
  839. //
  840. // If async, then only work if bltter isn't busy
  841. //
  842. if( dwFlags & DDBLT_ASYNC )
  843. {
  844. if(DRAW_ENGINE_BUSY(pThisDisplay))
  845. {
  846. DISPDBG((WRNLVL, "ASYNC Blit Failed" ));
  847. lpBlt->ddRVal = DDERR_WASSTILLDRAWING;
  848. START_SOFTWARE_CURSOR(pThisDisplay);
  849. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  850. return DDHAL_DRIVER_HANDLED;
  851. }
  852. #if DBG
  853. else
  854. {
  855. DISPDBG((DBGLVL, "ASYNC Blit Succeeded!"));
  856. }
  857. #endif
  858. }
  859. //
  860. // copy src/dest rects
  861. //
  862. rSrc = lpBlt->rSrc;
  863. rDest = lpBlt->rDest;
  864. rop = (BYTE) (lpBlt->bltFX.dwROP >> 16);
  865. // Switch to DirectDraw context
  866. DDRAW_OPERATION(pContext, pThisDisplay);
  867. if (dwFlags & DDBLT_ROP)
  868. {
  869. if (rop == (SRCCOPY >> 16))
  870. {
  871. DISPDBG((DBGLVL,"DDBLT_ROP: SRCCOPY"));
  872. if (pSrcLcl != NULL)
  873. {
  874. pSrcGbl = pSrcLcl->lpGbl;
  875. pFormatSource = _DD_SUR_GetSurfaceFormat(pSrcLcl);
  876. DISPDBG((DBGLVL, "Source Surface:"));
  877. DBGDUMP_DDRAWSURFACE_LCL(DBGLVL, pSrcLcl);
  878. }
  879. else
  880. {
  881. START_SOFTWARE_CURSOR(pThisDisplay);
  882. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  883. return DDHAL_DRIVER_NOTHANDLED;
  884. }
  885. #if DX7_TEXMANAGEMENT
  886. if ((pSrcLcl->lpSurfMore->ddsCapsEx.dwCaps2 &
  887. DDSCAPS2_TEXTUREMANAGE) ||
  888. (pDestLcl->lpSurfMore->ddsCapsEx.dwCaps2 &
  889. DDSCAPS2_TEXTUREMANAGE) )
  890. {
  891. // Managed source surface cases
  892. // (Including managed destination surfaces case)
  893. if (pSrcLcl->lpSurfMore->ddsCapsEx.dwCaps2 &
  894. DDSCAPS2_TEXTUREMANAGE)
  895. {
  896. if ((pDestLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) ||
  897. (pDestLcl->lpSurfMore->ddsCapsEx.dwCaps2 &
  898. DDSCAPS2_TEXTUREMANAGE) )
  899. {
  900. //-------------------------------------------------
  901. // Do the Managed surf -> sysmem | managed surf blt
  902. //-------------------------------------------------
  903. // make sure we'll reload the vidmem copy of the dest surf
  904. if (pDestLcl->lpSurfMore->ddsCapsEx.dwCaps2 &
  905. DDSCAPS2_TEXTUREMANAGE)
  906. {
  907. _D3D_TM_MarkDDSurfaceAsDirty(pThisDisplay,
  908. pDestLcl,
  909. TRUE);
  910. }
  911. _DD_BLT_SysMemToSysMemCopy(
  912. pSrcGbl->fpVidMem,
  913. pSrcGbl->lPitch,
  914. DDSurf_BitDepth(pSrcLcl),
  915. pDestGbl->fpVidMem,
  916. pDestGbl->lPitch,
  917. DDSurf_BitDepth(pDestLcl),
  918. &rSrc,
  919. &rDest);
  920. }
  921. else if ((pDestLcl->ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM))
  922. {
  923. //-------------------------------------------------
  924. // Do the Managed surf -> vidmem surf blt
  925. //-------------------------------------------------
  926. // This might be optimized by doing a vidmem->vidmem
  927. // when the source managed texture has a vidmem copy
  928. _DD_P3Download(pThisDisplay,
  929. pSrcGbl->fpVidMem,
  930. pDestGbl->fpVidMem,
  931. P3RX_LAYOUT_LINEAR,
  932. P3RX_LAYOUT_LINEAR,
  933. pSrcGbl->lPitch,
  934. pDestGbl->lPitch,
  935. DDSurf_GetPixelPitch(pDestLcl),
  936. DDSurf_GetChipPixelSize(pDestLcl),
  937. &rSrc,
  938. &rDest);
  939. }
  940. else
  941. {
  942. DISPDBG((ERRLVL,"Src-managed Tex DdBlt"
  943. " variation unimplemented!"));
  944. }
  945. goto Blt32Done;
  946. }
  947. // Managed destination surface cases
  948. if (pDestLcl->lpSurfMore->ddsCapsEx.dwCaps2 &
  949. DDSCAPS2_TEXTUREMANAGE)
  950. {
  951. if (pSrcLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)
  952. {
  953. //-------------------------------------------------
  954. // Do the sysmem surf -> managed surf blt
  955. //-------------------------------------------------
  956. // make sure we'll reload the vidmem copy of the dest surf
  957. _D3D_TM_MarkDDSurfaceAsDirty(pThisDisplay,
  958. pDestLcl,
  959. TRUE);
  960. _DD_BLT_SysMemToSysMemCopy(
  961. pSrcGbl->fpVidMem,
  962. pSrcGbl->lPitch,
  963. DDSurf_BitDepth(pSrcLcl),
  964. pDestGbl->fpVidMem,
  965. pDestGbl->lPitch,
  966. DDSurf_BitDepth(pDestLcl),
  967. &rSrc,
  968. &rDest);
  969. goto Blt32Done;
  970. }
  971. else if (pSrcLcl->ddsCaps.dwCaps & DDSCAPS_LOCALVIDMEM)
  972. {
  973. //-------------------------------------------------
  974. // Do the vidmem surf -> Managed surf blt
  975. //-------------------------------------------------
  976. // make sure we'll reload the
  977. // vidmem copy of the dest surf
  978. _D3D_TM_MarkDDSurfaceAsDirty(pThisDisplay,
  979. pDestLcl,
  980. TRUE);
  981. // Do slow mem mapped framebuffer blt into sysmem
  982. // The source surface lives in video mem so we need to get a
  983. // "real" sysmem address for it:
  984. _DD_BLT_SysMemToSysMemCopy(
  985. DDSURF_GETPOINTER(pSrcGbl, pThisDisplay),
  986. pSrcGbl->lPitch,
  987. DDSurf_BitDepth(pSrcLcl),
  988. pDestGbl->fpVidMem,
  989. pDestGbl->lPitch,
  990. DDSurf_BitDepth(pDestLcl),
  991. &rSrc,
  992. &rDest);
  993. }
  994. else
  995. {
  996. DISPDBG((ERRLVL,"Dest-managed Tex DdBlt"
  997. " variation unimplemented!"));
  998. }
  999. }
  1000. goto Blt32Done;
  1001. }
  1002. #endif // DX7_TEXMANAGEMENT
  1003. // Invalid cases...
  1004. if ((pFormatSource->DeviceFormat == SURF_YUV422) &&
  1005. (pFormatDest->DeviceFormat == SURF_CI8))
  1006. {
  1007. DISPDBG((ERRLVL,"Can't do this blit!"));
  1008. START_SOFTWARE_CURSOR(pThisDisplay);
  1009. lpBlt->ddRVal = DDERR_UNSUPPORTED;
  1010. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1011. return DDHAL_DRIVER_NOTHANDLED;
  1012. }
  1013. // Operation is System -> Video memory blit, as a texture
  1014. // download or an image download.
  1015. if (!(dwFlags & DDBLT_KEYDESTOVERRIDE) &&
  1016. (pSrcLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
  1017. (pDestLcl->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
  1018. {
  1019. DISPDBG((DBGLVL,"Being Asked to do SYSMEM->VIDMEM Blit"));
  1020. if (rop != (SRCCOPY >> 16))
  1021. {
  1022. DISPDBG((DBGLVL,"Being asked for non-copy ROP, refusing"));
  1023. lpBlt->ddRVal = DDERR_NORASTEROPHW;
  1024. START_SOFTWARE_CURSOR(pThisDisplay);
  1025. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1026. return DDHAL_DRIVER_NOTHANDLED;
  1027. }
  1028. DISPDBG((DBGLVL,"Doing image download"));
  1029. _DD_P3DownloadDD(pThisDisplay,
  1030. pSrcLcl,
  1031. pDestLcl,
  1032. pFormatSource,
  1033. pFormatDest,
  1034. &rSrc,
  1035. &rDest);
  1036. goto Blt32Done;
  1037. }
  1038. // Check for overlapping stretch blits.
  1039. // Are the surfaces the same?
  1040. if (pDestLcl->lpGbl->fpVidMem == pSrcLcl->lpGbl->fpVidMem)
  1041. {
  1042. // Do they overlap?
  1043. if ((!((rSrc.bottom < rDest.top) || (rSrc.top > rDest.bottom))) &&
  1044. (!((rSrc.right < rDest.left) || (rSrc.left > rDest.right))) )
  1045. {
  1046. // Are they of different source and dest sizes?
  1047. if ( ((rSrc.right - rSrc.left) != (rDest.right - rDest.left)) ||
  1048. ((rSrc.bottom - rSrc.top) != (rDest.bottom - rDest.top)) )
  1049. {
  1050. bOverlapStretch = TRUE;
  1051. }
  1052. }
  1053. }
  1054. // Is it a transparent blit?
  1055. if ( ( dwFlags & DDBLT_KEYSRCOVERRIDE ) ||
  1056. ( dwFlags & DDBLT_KEYDESTOVERRIDE ) )
  1057. {
  1058. DISPDBG((DBGLVL,"DDBLT_KEYSRCOVERRIDE"));
  1059. if (rop != (SRCCOPY >> 16))
  1060. {
  1061. lpBlt->ddRVal = DDERR_NORASTEROPHW;
  1062. START_SOFTWARE_CURSOR(pThisDisplay);
  1063. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1064. return DDHAL_DRIVER_NOTHANDLED;
  1065. }
  1066. // If the surface sizes don't match, then we are stretching.
  1067. // If the surfaces are flipped then do it this was for now...
  1068. if (((rSrc.right - rSrc.left) != (rDest.right - rDest.left) ||
  1069. (rSrc.bottom - rSrc.top) != (rDest.bottom - rDest.top) ) ||
  1070. ((dwFlags & DDBLT_DDFX) &&
  1071. ((lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN) ||
  1072. (lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT)) ) )
  1073. {
  1074. if (!bOverlapStretch)
  1075. {
  1076. // Use generic rout.
  1077. _DD_P3BltStretchSrcChDstCh_DD(pThisDisplay,
  1078. pSrcLcl,
  1079. pDestLcl,
  1080. pFormatSource,
  1081. pFormatDest,
  1082. lpBlt,
  1083. &rSrc,
  1084. &rDest);
  1085. }
  1086. else
  1087. {
  1088. // Stretched overlapped blits (DCT case)
  1089. _DD_P3BltStretchSrcChDstChOverlap(pThisDisplay,
  1090. pSrcLcl,
  1091. pDestLcl,
  1092. pFormatSource,
  1093. pFormatDest,
  1094. lpBlt,
  1095. &rSrc,
  1096. &rDest);
  1097. }
  1098. }
  1099. else if ( dwFlags & DDBLT_KEYDESTOVERRIDE )
  1100. {
  1101. if ((pSrcLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
  1102. (pDestLcl->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
  1103. {
  1104. DISPDBG((DBGLVL,"Being Asked to do SYSMEM->VIDMEM "
  1105. "Blit with DestKey"));
  1106. if (rop != (SRCCOPY >> 16))
  1107. {
  1108. DISPDBG((DBGLVL,"Being asked for non-copy "
  1109. "ROP, refusing"));
  1110. lpBlt->ddRVal = DDERR_NORASTEROPHW;
  1111. START_SOFTWARE_CURSOR(pThisDisplay);
  1112. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1113. return DDHAL_DRIVER_NOTHANDLED;
  1114. }
  1115. // A download routine that does destination colorkey.
  1116. _DD_P3DownloadDstCh(pThisDisplay,
  1117. pSrcLcl,
  1118. pDestLcl,
  1119. pFormatSource,
  1120. pFormatDest,
  1121. lpBlt,
  1122. &rSrc,
  1123. &rDest);
  1124. }
  1125. else
  1126. {
  1127. _DD_P3BltStretchSrcChDstCh_DD(pThisDisplay,
  1128. pSrcLcl,
  1129. pDestLcl,
  1130. pFormatSource,
  1131. pFormatDest,
  1132. lpBlt,
  1133. &rSrc,
  1134. &rDest);
  1135. }
  1136. }
  1137. else
  1138. {
  1139. if (DDSurf_IsAGP(pSrcLcl))
  1140. {
  1141. // Need this rout if we are in
  1142. // AGP memory because this textures
  1143. _DD_P3BltStretchSrcChDstCh_DD(pThisDisplay,
  1144. pSrcLcl,
  1145. pDestLcl,
  1146. pFormatSource,
  1147. pFormatDest,
  1148. lpBlt,
  1149. &rSrc,
  1150. &rDest);
  1151. }
  1152. else
  1153. {
  1154. // Only source keying, and no stretching.
  1155. _DD_P3BltSourceChroma(pThisDisplay,
  1156. pSrcLcl,
  1157. pDestLcl,
  1158. pFormatSource,
  1159. pFormatDest,
  1160. lpBlt,
  1161. &rSrc,
  1162. &rDest);
  1163. }
  1164. }
  1165. goto Blt32Done;
  1166. }
  1167. else
  1168. {
  1169. // If the surface sizes don't match, then we are stretching.
  1170. // If the surfaces are flipped then do it this was for now...
  1171. if (((rSrc.right - rSrc.left) != (rDest.right - rDest.left) ||
  1172. (rSrc.bottom - rSrc.top) != (rDest.bottom - rDest.top)) ||
  1173. ((lpBlt->dwFlags & DDBLT_DDFX) &&
  1174. ((lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN) ||
  1175. (lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT))))
  1176. {
  1177. // Is a stretch blit
  1178. DISPDBG((DBGLVL,"DDBLT_ROP: STRETCHCOPYBLT OR "
  1179. "MIRROR OR BOTH"));
  1180. // Can't rop during a stretch blit.
  1181. if (rop != (SRCCOPY >> 16))
  1182. {
  1183. lpBlt->ddRVal = DDERR_NORASTEROPHW;
  1184. START_SOFTWARE_CURSOR(pThisDisplay);
  1185. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1186. return DDHAL_DRIVER_NOTHANDLED;
  1187. }
  1188. // Do the stretch
  1189. if (!bOverlapStretch)
  1190. {
  1191. // Use the generic rout ATM.
  1192. _DD_P3BltStretchSrcChDstCh_DD(pThisDisplay,
  1193. pSrcLcl,
  1194. pDestLcl,
  1195. pFormatSource,
  1196. pFormatDest,
  1197. lpBlt,
  1198. &rSrc,
  1199. &rDest);
  1200. }
  1201. else
  1202. {
  1203. // DCT case - Stretched overlapped blits
  1204. _DD_P3BltStretchSrcChDstChOverlap(pThisDisplay,
  1205. pSrcLcl,
  1206. pDestLcl,
  1207. pFormatSource,
  1208. pFormatDest,
  1209. lpBlt,
  1210. &rSrc,
  1211. &rDest);
  1212. }
  1213. }
  1214. else // ! Stretching
  1215. {
  1216. // Must be a standard blit.
  1217. DISPDBG((DBGLVL,"DDBLT_ROP: COPYBLT"));
  1218. DISPDBG((DBGLVL,"Standard Copy Blit"));
  1219. // If the source is in AGP, use a texturing blitter.
  1220. if ((DDSurf_IsAGP(pSrcLcl)) ||
  1221. ((pFormatSource->DeviceFormat == SURF_YUV422) &&
  1222. (pFormatDest->DeviceFormat != SURF_YUV422)))
  1223. {
  1224. _DD_P3BltStretchSrcChDstCh_DD(pThisDisplay,
  1225. pSrcLcl,
  1226. pDestLcl,
  1227. pFormatSource,
  1228. pFormatDest,
  1229. lpBlt,
  1230. &rSrc,
  1231. &rDest);
  1232. }
  1233. else
  1234. {
  1235. // A standard, boring blit.
  1236. // Call the correct CopyBlt Function.
  1237. _DD_BLT_P3CopyBltDD(pThisDisplay,
  1238. pSrcLcl,
  1239. pDestLcl,
  1240. pFormatSource,
  1241. pFormatDest,
  1242. &rSrc,
  1243. &rDest);
  1244. }
  1245. }
  1246. goto Blt32Done;
  1247. }
  1248. }
  1249. else if ((rop == (BLACKNESS >> 16)) || (rop == (WHITENESS >> 16)))
  1250. {
  1251. DWORD color;
  1252. DISPDBG((DBGLVL,"DDBLT_ROP: BLACKNESS or WHITENESS"));
  1253. if (rop == (BLACKNESS >> 16))
  1254. {
  1255. color = 0;
  1256. }
  1257. else
  1258. {
  1259. color = 0xffffffff;
  1260. }
  1261. _DD_BLT_P3ClearDD(pThisDisplay,
  1262. pDestLcl,
  1263. pFormatDest,
  1264. &rDest,
  1265. color,
  1266. FALSE,
  1267. FALSE);
  1268. }
  1269. else if ((rop & 7) != ((rop >> 4) & 7))
  1270. {
  1271. lpBlt->ddRVal = DDERR_NORASTEROPHW;
  1272. START_SOFTWARE_CURSOR(pThisDisplay);
  1273. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1274. return DDHAL_DRIVER_NOTHANDLED;
  1275. }
  1276. else
  1277. {
  1278. DISPDBG((WRNLVL,"P3 BLT case not found!"));
  1279. START_SOFTWARE_CURSOR(pThisDisplay);
  1280. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1281. return DDHAL_DRIVER_NOTHANDLED;
  1282. }
  1283. }
  1284. else if (dwFlags & DDBLT_COLORFILL)
  1285. {
  1286. DISPDBG((DBGLVL,"DDBLT_COLORFILL(P3): Color=0x%x",
  1287. lpBlt->bltFX.dwFillColor));
  1288. #if DX7_TEXMANAGEMENT
  1289. // If clearing a driver managed texture, clear just the sysmem copy
  1290. if (pDestLcl->lpSurfMore->ddsCapsEx.dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  1291. {
  1292. _DD_BLT_P3ClearManagedSurf(DDSurf_GetChipPixelSize(pDestLcl),
  1293. &rDest,
  1294. pDestGbl->fpVidMem,
  1295. pDestGbl->lPitch,
  1296. lpBlt->bltFX.dwFillColor);
  1297. _D3D_TM_MarkDDSurfaceAsDirty(pThisDisplay,
  1298. pDestLcl,
  1299. TRUE);
  1300. }
  1301. else
  1302. #endif // DX7_TEXMANAGEMENT
  1303. {
  1304. _DD_BLT_P3ClearDD(pThisDisplay,
  1305. pDestLcl,
  1306. pFormatDest,
  1307. &rDest,
  1308. lpBlt->bltFX.dwFillColor,
  1309. FALSE,
  1310. FALSE);
  1311. }
  1312. }
  1313. else if (dwFlags & DDBLT_DEPTHFILL ||
  1314. ((dwFlags & DDBLT_COLORFILL) &&
  1315. (pDestLcl->ddsCaps.dwCaps & DDSCAPS_ZBUFFER)))
  1316. {
  1317. DISPDBG((DBGLVL,"DDBLT_DEPTHFILL(P3): Value=0x%x",
  1318. lpBlt->bltFX.dwFillColor));
  1319. _DD_BLT_P3ClearDD(pThisDisplay,
  1320. pDestLcl,
  1321. pFormatDest,
  1322. &rDest,
  1323. lpBlt->bltFX.dwFillColor,
  1324. TRUE,
  1325. TRUE);
  1326. }
  1327. else
  1328. {
  1329. START_SOFTWARE_CURSOR(pThisDisplay);
  1330. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1331. return DDHAL_DRIVER_NOTHANDLED;
  1332. }
  1333. Blt32Done:
  1334. if ((pDestLcl->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) ||
  1335. (pDestLcl->ddsCaps.dwCaps & DDSCAPS_FRONTBUFFER))
  1336. {
  1337. P3_DMA_DEFS();
  1338. DISPDBG((DBGLVL,"Flushing DMA due to primary target in DDRAW"));
  1339. P3_DMA_GET_BUFFER();
  1340. P3_DMA_FLUSH_BUFFER();
  1341. }
  1342. START_SOFTWARE_CURSOR(pThisDisplay);
  1343. lpBlt->ddRVal = DD_OK;
  1344. DBG_CB_EXIT(DdBlt,lpBlt->ddRVal);
  1345. return DDHAL_DRIVER_HANDLED;
  1346. } // DdBlt