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.

524 lines
18 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *********************
  4. * * DDraw SAMPLE CODE *
  5. * *********************
  6. *
  7. * Module Name: ddblt.c
  8. *
  9. * Content: DirectDraw Blt and AlphaBlt callbacks
  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 "directx.h"
  16. #include "dd.h"
  17. //
  18. // lookup table to get shift values from Permedia format definition
  19. DWORD ShiftLookup[5] = { 0, 0, 1, 0, 2};
  20. //@@BEGIN_DDKSPLIT
  21. #if DX7_ALPHABLT
  22. //---------------------------------------------------------------------------
  23. // BOOL Intersect
  24. //
  25. // Function:
  26. // Check the integration of two input rectangles (RECTL* pRcl1,
  27. // RECTL* pRcl2) and set the intersection result in (RECTL* pRclResult)
  28. //
  29. // Return:
  30. // TRUE---If 'prcl1' and 'prcl2' intersect. The intersection will be in
  31. // 'prclResult'
  32. // FALSE--If they don't intersect. 'prclResult' is undefined.
  33. //
  34. //---------------------------------------------------------------------------
  35. BOOL
  36. Intersect(RECTL* pRcl1,
  37. RECT* pRcl2,
  38. RECTL* pRclResult)
  39. {
  40. pRclResult->left = max(pRcl1->left, pRcl2->left);
  41. pRclResult->right = min(pRcl1->right, pRcl2->right);
  42. //
  43. // Check if there is a horizontal intersection
  44. //
  45. if ( pRclResult->left < pRclResult->right )
  46. {
  47. pRclResult->top = max(pRcl1->top, pRcl2->top);
  48. pRclResult->bottom = min(pRcl1->bottom, pRcl2->bottom);
  49. //
  50. // Check if there a vertical intersection
  51. //
  52. if (pRclResult->top < pRclResult->bottom)
  53. return(TRUE);
  54. }
  55. //
  56. // Return FALSE if there is no intersection
  57. //
  58. return(FALSE);
  59. }// Intersect()
  60. //-----------------------------------------------------------------------------
  61. // IsDstRectClipped
  62. //
  63. // check if the destination rectangle of a blit is clipped by the given clip
  64. // rectangles. The function takes the rectangles as is and there can be cases
  65. // where a dest. rectangle is not clipped, but do not detect it...
  66. //
  67. // pDstRect---destination rectangle for blt
  68. // iClipRects-number of clip regions
  69. // pClipRects-clipping regions
  70. //
  71. //Return:
  72. // TRUE---dest rectangle is clipped
  73. // FALSE--dest rectangle is not clipped
  74. //-----------------------------------------------------------------------------
  75. BOOL
  76. IsDstRectClipped(RECTL *pDstRect,
  77. INT iClipRects,
  78. RECT *pClipRects)
  79. {
  80. INT i;
  81. RECTL rClippedRect;
  82. for ( i=0; i<iClipRects; i++)
  83. {
  84. if (Intersect( pDstRect, &pClipRects[i], &rClippedRect))
  85. {
  86. if (pDstRect->left==rClippedRect.left &&
  87. pDstRect->right==rClippedRect.right &&
  88. pDstRect->top==rClippedRect.top &&
  89. pDstRect->bottom==rClippedRect.bottom
  90. )
  91. {
  92. // dest rect is not clipped!!!
  93. return FALSE;
  94. }
  95. }
  96. }
  97. return TRUE;
  98. }
  99. #endif
  100. //@@END_DDKSPLIT
  101. //-----------------------------------------------------------------------------
  102. //
  103. // DdPermediaBlt
  104. //
  105. // implements DirectDraw Blt callback
  106. //
  107. // lpBlt----structure for passing information to DDHAL Blt
  108. //
  109. //-----------------------------------------------------------------------------
  110. DWORD CALLBACK
  111. DdBlt( LPDDHAL_BLTDATA lpBlt )
  112. {
  113. PPDev ppdev=(PPDev)lpBlt->lpDD->dhpdev;
  114. PERMEDIA_DEFS(ppdev);
  115. DWORD dwWindowBase;
  116. RECTL rSrc;
  117. RECTL rDest;
  118. DWORD dwFlags;
  119. LONG lPixPitchDest;
  120. LONG lPixPitchSrc;
  121. HRESULT ddrval;
  122. LPDDRAWI_DDRAWSURFACE_LCL pSrcLcl;
  123. LPDDRAWI_DDRAWSURFACE_LCL pDestLcl;
  124. LPDDRAWI_DDRAWSURFACE_GBL pSrcGbl;
  125. LPDDRAWI_DDRAWSURFACE_GBL pDestGbl;
  126. PermediaSurfaceData* pPrivateSource;
  127. PermediaSurfaceData* pPrivateDest;
  128. pDestLcl = lpBlt->lpDDDestSurface;
  129. pSrcLcl = lpBlt->lpDDSrcSurface;
  130. DBG_DD((2,"DDraw: Blt, ppdev: 0x%x",ppdev));
  131. pDestGbl = pDestLcl->lpGbl;
  132. pPrivateDest= (PermediaSurfaceData*)pDestGbl->dwReserved1;
  133. DD_CHECK_PRIMARY_SURFACE_DATA(pDestLcl,pPrivateDest);
  134. DBG_DD((10, "Dest Surface:"));
  135. DUMPSURFACE(10, pDestLcl, NULL);
  136. ULONG ulDestPixelShift=DDSurf_GetPixelShift(pDestLcl);
  137. dwFlags = lpBlt->dwFlags;
  138. // For the future, drivers should ignore the DDBLT_ASYNC
  139. // flag, because its hardly used by applications and
  140. // nowadays drivers can queue up lots of blits, so that
  141. // the applications do not have to wait for it.
  142. // get local copy of src and dest rect
  143. rSrc = lpBlt->rSrc;
  144. rDest = lpBlt->rDest;
  145. // Switch to DirectDraw context
  146. DDCONTEXT;
  147. if (DDSurf_BitDepth(pDestLcl)==24)
  148. {
  149. return DDHAL_DRIVER_NOTHANDLED;
  150. }
  151. dwWindowBase = (DWORD)((UINT_PTR)(pDestGbl->fpVidMem) >>
  152. ulDestPixelShift);
  153. // get pitch for destination in pixels
  154. lPixPitchDest = pDestGbl->lPitch >> ulDestPixelShift;
  155. if (dwFlags & DDBLT_ROP)
  156. {
  157. if ((lpBlt->bltFX.dwROP >> 16) != (SRCCOPY >> 16))
  158. {
  159. DBG_DD((1,"DDraw:Blt:BLT ROP case not supported!"));
  160. return DDHAL_DRIVER_NOTHANDLED;
  161. }
  162. LONG srcOffset;
  163. DBG_DD((3,"DDBLT_ROP: SRCCOPY"));
  164. if (pSrcLcl != NULL)
  165. {
  166. pSrcGbl = pSrcLcl->lpGbl;
  167. pPrivateSource = (PermediaSurfaceData*)pSrcGbl->dwReserved1;
  168. DD_CHECK_PRIMARY_SURFACE_DATA(pSrcLcl,pPrivateSource);
  169. DBG_DD((10, "Source Surface:"));
  170. DUMPSURFACE(10, pSrcLcl, NULL);
  171. }
  172. else
  173. {
  174. return DDHAL_DRIVER_NOTHANDLED;
  175. }
  176. if (DDSurf_BitDepth(pSrcLcl)==24)
  177. return DDHAL_DRIVER_NOTHANDLED;
  178. // determine src pitch in pixels
  179. lPixPitchSrc = pSrcGbl->lPitch >> ulDestPixelShift;
  180. // Operation is System -> Video memory blit,
  181. // as a texture download or an image download.
  182. if ((pSrcLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
  183. (pDestLcl->ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
  184. {
  185. ASSERTDD(!(pDestLcl->ddsCaps.dwCaps & DDSCAPS_NONLOCALVIDMEM),
  186. "unsupported texture download to AGP memory");
  187. if ((pDestLcl->lpSurfMore->ddsCapsEx.dwCaps2 &
  188. DDSCAPS2_TEXTUREMANAGE)
  189. && (NULL != pPrivateDest)
  190. )
  191. {
  192. // texture download
  193. DBG_DD((3,"SYSMEM->MANAGED MEM Blit"
  194. "(texture to system memory)"));
  195. pPrivateDest->dwFlags |= P2_SURFACE_NEEDUPDATE;
  196. SysMemToSysMemSurfaceCopy(
  197. pSrcGbl->fpVidMem,
  198. pSrcGbl->lPitch,
  199. DDSurf_BitDepth(pSrcLcl),
  200. pDestGbl->fpVidMem,
  201. pDestGbl->lPitch,
  202. DDSurf_BitDepth(pDestLcl),
  203. &rSrc,
  204. &rDest);
  205. goto BltDone;
  206. }
  207. else
  208. if (pPrivateDest!=NULL)
  209. {
  210. if ( (pDestLcl->ddsCaps.dwCaps & DDSCAPS_TEXTURE) &&
  211. ((rSrc.right-rSrc.left)==(LONG)pSrcGbl->wWidth) &&
  212. ((rSrc.bottom-rSrc.top)==(LONG)pSrcGbl->wHeight)
  213. )
  214. {
  215. //
  216. // patched texture download can only be done
  217. // when the texture is downloaded as a whole!
  218. //
  219. DBG_DD((3,"SYSMEM->VIDMEM Blit (texture to videomemory)"));
  220. PermediaPatchedTextureDownload(
  221. ppdev,
  222. pPrivateDest,
  223. pSrcGbl->fpVidMem,
  224. pSrcGbl->lPitch,
  225. &rSrc,
  226. pDestGbl->fpVidMem,
  227. pDestGbl->lPitch,
  228. &rDest);
  229. }
  230. else
  231. {
  232. // Image download
  233. DBG_DD((3,"SYSMEM->VIDMEM Blit (system to videomemory)"));
  234. PermediaPackedDownload(
  235. ppdev,
  236. pPrivateDest,
  237. pSrcLcl,
  238. &rSrc,
  239. pDestLcl,
  240. &rDest);
  241. }
  242. goto BltDone;
  243. } else
  244. {
  245. DBG_DD((0,"DDraw: Blt, privatedest invalid"));
  246. return DDHAL_DRIVER_NOTHANDLED;
  247. }
  248. }
  249. if (pPrivateSource == NULL ||
  250. pPrivateDest == NULL)
  251. {
  252. DBG_DD((0,"DDraw: Blt, privatesource or dest invalid"));
  253. return DDHAL_DRIVER_NOTHANDLED;
  254. }
  255. BOOL bNonLocalToVideo=FALSE;
  256. // set base of source
  257. if ( DDSCAPS_NONLOCALVIDMEM & pSrcLcl->ddsCaps.dwCaps)
  258. {
  259. // turn on AGP bus texture source
  260. srcOffset = (LONG) DD_AGPSURFACEPHYSICAL(pSrcGbl);
  261. srcOffset |= 1 << 30;
  262. bNonLocalToVideo=TRUE;
  263. } else
  264. {
  265. srcOffset = (LONG)((pSrcGbl->fpVidMem) >>
  266. pPrivateSource->SurfaceFormat.PixelSize);
  267. }
  268. // Operation is YUV->RGB conversion
  269. if ((pPrivateSource != NULL) &&
  270. (pPrivateSource->SurfaceFormat.Format == PERMEDIA_YUV422) &&
  271. (pPrivateSource->SurfaceFormat.FormatExtension
  272. == PERMEDIA_YUV422_EXTENSION))
  273. {
  274. DBG_DD((3,"YUV to RGB blt"));
  275. // We are only doing blits from YUV422 to RGB !
  276. if (pPrivateDest->SurfaceFormat.Format != PERMEDIA_YUV422)
  277. {
  278. DBG_DD((4,"Blitting from Source YUV to RGB"));
  279. // YUV to RGB blt
  280. PermediaYUVtoRGB( ppdev,
  281. &lpBlt->bltFX,
  282. pPrivateDest,
  283. pPrivateSource,
  284. &rDest,
  285. &rSrc,
  286. dwWindowBase,
  287. srcOffset);
  288. goto BltDone;
  289. }
  290. else
  291. {
  292. DBG_DD((0,"Couldn't handle YUV to YUV blt"));
  293. lpBlt->ddRVal = DD_OK;
  294. return DDHAL_DRIVER_NOTHANDLED;
  295. }
  296. }
  297. ASSERTDD(DDSurf_BitDepth(pSrcLcl)==DDSurf_BitDepth(pDestLcl),
  298. "Blt between surfaces of different"
  299. "color depths are not supported");
  300. BOOL bMirror=(dwFlags & DDBLT_DDFX)==DDBLT_DDFX;
  301. if (bMirror)
  302. {
  303. bMirror= (lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORUPDOWN) ||
  304. (lpBlt->bltFX.dwDDFX & DDBLTFX_MIRRORLEFTRIGHT);
  305. }
  306. BOOL bStretched=((rSrc.right - rSrc.left) !=
  307. (rDest.right - rDest.left) ||
  308. (rSrc.bottom - rSrc.top) !=
  309. (rDest.bottom - rDest.top));
  310. // Is it a colorkey blt?
  311. if (dwFlags & DDBLT_KEYSRCOVERRIDE)
  312. {
  313. DBG_DD((3,"DDBLT_KEYSRCOVERRIDE"));
  314. // If the surface sizes don't match, then we are stretching.
  315. if (bStretched || bMirror)
  316. {
  317. PermediaStretchCopyChromaBlt( ppdev,
  318. lpBlt,
  319. pPrivateDest,
  320. pPrivateSource,
  321. &rDest,
  322. &rSrc,
  323. dwWindowBase,
  324. srcOffset);
  325. }
  326. else
  327. {
  328. PermediaSourceChromaBlt( ppdev,
  329. lpBlt,
  330. pPrivateDest,
  331. pPrivateSource,
  332. &rDest,
  333. &rSrc,
  334. dwWindowBase,
  335. srcOffset);
  336. }
  337. goto BltDone;
  338. }
  339. else
  340. {
  341. // If the surface sizes don't match, then we are stretching.
  342. // Also the blits from Nonlocal- to Videomemory have to go through
  343. // the texture unit!
  344. if ( bStretched || bMirror || bNonLocalToVideo)
  345. {
  346. DBG_DD((3,"DDBLT_ROP: STRETCHCOPYBLT OR "
  347. "MIRROR OR BOTH OR AGPVIDEO"));
  348. PermediaStretchCopyBlt( ppdev,
  349. lpBlt,
  350. pPrivateDest,
  351. pPrivateSource,
  352. &rDest,
  353. &rSrc,
  354. dwWindowBase,
  355. srcOffset);
  356. }
  357. else
  358. {
  359. DBG_DD((3,"DDBLT_ROP: COPYBLT %08lx %08lx %08lx",
  360. pSrcGbl->fpVidMem,pDestGbl->fpVidMem,ulDestPixelShift));
  361. // Work out the source offset
  362. // (offset in pixels from dst to src)
  363. srcOffset = (LONG)((pSrcGbl->fpVidMem - pDestGbl->fpVidMem)
  364. >> ulDestPixelShift);
  365. // For some reason, the user might want
  366. // to do a conversion on the data as it is
  367. // blitted from VRAM->VRAM by turning on Patching.
  368. // If Surf1Patch XOR Surf2Patch then
  369. // do a special blit that isn't packed and does patching.
  370. if (((pPrivateDest->dwFlags & P2_CANPATCH) ^
  371. (pPrivateSource->dwFlags & P2_CANPATCH))
  372. & P2_CANPATCH)
  373. {
  374. DBG_DD((4,"Doing Patch-Conversion!"));
  375. PermediaPatchedCopyBlt( ppdev,
  376. lPixPitchDest,
  377. lPixPitchSrc,
  378. pPrivateDest,
  379. pPrivateSource,
  380. &rDest,
  381. &rSrc,
  382. dwWindowBase,
  383. srcOffset);
  384. }
  385. else
  386. {
  387. PermediaPackedCopyBlt( ppdev,
  388. lPixPitchDest,
  389. lPixPitchSrc,
  390. pPrivateDest,
  391. pPrivateSource,
  392. &rDest,
  393. &rSrc,
  394. dwWindowBase,
  395. srcOffset);
  396. }
  397. }
  398. goto BltDone;
  399. }
  400. }
  401. else if (pPrivateDest==NULL)
  402. {
  403. DBG_DD((0,"Private Surface data invalid!"));
  404. DUMPSURFACE(0, pDestLcl, NULL);
  405. } else if (dwFlags & DDBLT_COLORFILL)
  406. {
  407. DBG_DD((3,"DDBLT_COLORFILL: Color=0x%x", lpBlt->bltFX.dwFillColor));
  408. if (pDestLcl->lpSurfMore->ddsCapsEx.dwCaps2 &
  409. DDSCAPS2_TEXTUREMANAGE)
  410. {
  411. PermediaClearManagedSurface(pPrivateDest->SurfaceFormat.PixelSize,
  412. &rDest,
  413. pDestGbl->fpVidMem,
  414. pDestGbl->lPitch,
  415. lpBlt->bltFX.dwFillColor);
  416. pPrivateDest->dwFlags |= P2_SURFACE_NEEDUPDATE;
  417. }
  418. else
  419. {
  420. PermediaFastClear( ppdev,
  421. pPrivateDest,
  422. &rDest,
  423. dwWindowBase,
  424. lpBlt->bltFX.dwFillColor);
  425. }
  426. }
  427. else if (dwFlags & DDBLT_DEPTHFILL)
  428. {
  429. DBG_DD((3,"DDBLT_DEPTHFILL: Value=0x%x", lpBlt->bltFX.dwFillColor));
  430. // Work out the window base for the LB clear, acount for the depth size
  431. dwWindowBase = (DWORD)((UINT_PTR)(pDestGbl->fpVidMem)
  432. >> __PERMEDIA_16BITPIXEL);
  433. // Call the LB Solid Fill Function.
  434. PermediaFastLBClear( ppdev,
  435. pPrivateDest,
  436. &rDest,
  437. dwWindowBase,
  438. lpBlt->bltFX.dwFillColor);
  439. }
  440. else
  441. {
  442. DBG_DD((1,"DDraw:Blt:Blt case not supported %08lx", dwFlags));
  443. return DDHAL_DRIVER_NOTHANDLED;
  444. }
  445. BltDone:
  446. lpBlt->ddRVal = DD_OK;
  447. return DDHAL_DRIVER_HANDLED;
  448. } // DdBlt ()