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.

1108 lines
41 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * D3D SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: d3dhw.c
  8. *
  9. * Content: Hardware dependent texture setup for D3D
  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 "d3dhw.h"
  16. #include "d3dcntxt.h"
  17. #include "d3ddelta.h"
  18. #include "dd.h"
  19. #include "heap.h"
  20. #include "d3dtxman.h"
  21. //-----------------------------------------------------------------------------
  22. //
  23. // PERMEDIA_D3DTEXTURE *TextureHandleToPtr
  24. //
  25. // Find the texture associated to a given texture handle vale (which is to
  26. // say , to a surface handle )
  27. //
  28. //-----------------------------------------------------------------------------
  29. PERMEDIA_D3DTEXTURE *
  30. TextureHandleToPtr(UINT_PTR thandle, PERMEDIA_D3DCONTEXT* pContext)
  31. {
  32. // only a DX7 context can get here
  33. ASSERTDD(NULL != pContext->pHandleList,
  34. "pHandleList==NULL in TextureHandleToPtr");
  35. if (pContext->pHandleList->dwSurfaceList == NULL)
  36. {
  37. // avoid AV if our surface list is missing
  38. return NULL;
  39. }
  40. if ((PtrToUlong(pContext->pHandleList->dwSurfaceList[0]) > thandle) &&
  41. (0 != thandle))
  42. {
  43. return pContext->pHandleList->dwSurfaceList[(DWORD)thandle];
  44. }
  45. // Request for pointer for an invalid handle returns NULL
  46. return NULL;
  47. } // TextureHandleToPtr
  48. //-----------------------------------------------------------------------------
  49. //
  50. // PERMEDIA_D3DTEXTURE *PaletteHandleToPtr
  51. //
  52. //-----------------------------------------------------------------------------
  53. PERMEDIA_D3DPALETTE *
  54. PaletteHandleToPtr(UINT_PTR phandle, PERMEDIA_D3DCONTEXT* pContext)
  55. {
  56. ASSERTDD(NULL != pContext->pHandleList,
  57. "pHandleList==NULL in PaletteHandleToPtr");
  58. if ( (NULL != pContext->pHandleList->dwPaletteList) &&
  59. (PtrToUlong(pContext->pHandleList->dwPaletteList[0]) > phandle) &&
  60. (0 != phandle)
  61. )
  62. {
  63. return pContext->pHandleList->dwPaletteList[(DWORD)phandle];
  64. }
  65. return NULL;
  66. } // PaletteHandleToPtr
  67. //-----------------------------------------------------------------------------
  68. //
  69. //void StorePermediaLODLevel
  70. //
  71. // Store private data specific to a level of detail
  72. //
  73. //-----------------------------------------------------------------------------
  74. void
  75. StorePermediaLODLevel(PPDev ppdev,
  76. PERMEDIA_D3DTEXTURE* pTexture,
  77. LPDDRAWI_DDRAWSURFACE_LCL pSurf,
  78. int LOD)
  79. {
  80. DWORD dwPartialWidth;
  81. int iPixelSize;
  82. DBG_D3D((10,"Entering StorePermediaLODLevel"));
  83. // if it's any surface type that's not created by driver
  84. // certainly there's no need to texture it
  85. if (NULL == pTexture->pTextureSurface)
  86. return;
  87. // Get the BYTE Offset to the texture map
  88. if (DDSCAPS_NONLOCALVIDMEM & pTexture->dwCaps)
  89. {
  90. pTexture->MipLevels[LOD].PixelOffset =
  91. (DWORD)(DD_AGPSURFACEPHYSICAL(pSurf->lpGbl) - ppdev->dwGARTDev);
  92. }
  93. else
  94. {
  95. pTexture->MipLevels[LOD].PixelOffset = (DWORD)pSurf->lpGbl->fpVidMem;
  96. }
  97. // .. Convert it to Pixels
  98. switch(pTexture->pTextureSurface->SurfaceFormat.PixelSize)
  99. {
  100. case __PERMEDIA_4BITPIXEL:
  101. pTexture->MipLevels[LOD].PixelOffset <<= 1;
  102. break;
  103. case __PERMEDIA_8BITPIXEL: /* No Change*/
  104. break;
  105. case __PERMEDIA_16BITPIXEL:
  106. pTexture->MipLevels[LOD].PixelOffset >>= 1;
  107. break;
  108. case __PERMEDIA_24BITPIXEL:
  109. pTexture->MipLevels[LOD].PixelOffset /= 3;
  110. break;
  111. case __PERMEDIA_32BITPIXEL:
  112. pTexture->MipLevels[LOD].PixelOffset >>= 2;
  113. break;
  114. default:
  115. ASSERTDD(0,"Invalid Texture Pixel Size!");
  116. pTexture->MipLevels[LOD].PixelOffset >>= 1;
  117. break;
  118. }
  119. // P2 recognises that the texture is AGP if you set bit 30 to be 1.
  120. if (DDSCAPS_NONLOCALVIDMEM & pTexture->dwCaps)
  121. {
  122. pTexture->MipLevels[LOD].PixelOffset |= (1 << 30);
  123. }
  124. DBG_D3D((4,"Storing LOD: %d, Pitch: %d, Width: %d PixelOffset=%08lx",
  125. LOD, pSurf->lpGbl->lPitch,
  126. pSurf->lpGbl->wWidth,pTexture->MipLevels[LOD].PixelOffset));
  127. // Get the Partial Products for this LOD
  128. iPixelSize = pTexture->pTextureSurface->SurfaceFormat.PixelSize;
  129. if (iPixelSize == __PERMEDIA_4BITPIXEL)
  130. {
  131. dwPartialWidth = (pSurf->lpGbl->lPitch << 1);
  132. }
  133. else
  134. {
  135. if (iPixelSize != __PERMEDIA_24BITPIXEL)
  136. {
  137. dwPartialWidth = (pSurf->lpGbl->lPitch >> iPixelSize);
  138. }
  139. else
  140. {
  141. dwPartialWidth = pSurf->lpGbl->lPitch / 3;
  142. }
  143. }
  144. if (dwPartialWidth < 32)
  145. dwPartialWidth = 32;
  146. vCalcPackedPP( dwPartialWidth, NULL, &pTexture->MipLevels[LOD].ulPackedPP);
  147. pTexture->MipLevels[LOD].logWidth = log2((int)pSurf->lpGbl->wWidth);
  148. pTexture->MipLevels[LOD].logHeight = log2((int)pSurf->lpGbl->wHeight);
  149. DBG_D3D((10,"Exiting StorePermediaLODLevel"));
  150. } // StorePermediaLODLevel
  151. //@@BEGIN_DDKSPLIT
  152. // Note: we are currently not using more than 8MB of AGP memory
  153. #if 0
  154. //-----------------------------------------------------------------------------
  155. //
  156. // BOOL CheckAGPTexturePage
  157. //
  158. // Check that the AGP texture we are about to use hasn't been placed
  159. // in a different 8MB page.
  160. // dwGARTDev represents our current base address for the AGP texture memory
  161. // dwGARTDevBase is the value we were passed at start of day
  162. //-----------------------------------------------------------------------------
  163. BOOL CheckAGPTexturePage(PPDev ppdev,
  164. PERMEDIA_D3DCONTEXT* pContext,
  165. PERMEDIA_D3DTEXTURE* pTexture,
  166. LPDDRAWI_DDRAWSURFACE_LCL pSurf)
  167. {
  168. BOOL bChanged = FALSE;
  169. DBG_D3D((10,"Entering CheckAGPTexturePage"));
  170. ASSERTDD(pSurf, "ERROR: NULL Surface passed to CheckAGPTexturePage!");
  171. // Calculate the offset to the texture from the current
  172. // base pointer in AGP memory
  173. UINT_PTR lSurfaceOffset = pTexture->lSurfaceOffset;
  174. UINT_PTR lTextureSize = pTexture->wHeight * pTexture->lPitch;
  175. // Account for a potential LUT added to the end of the surface
  176. lTextureSize += (256 * sizeof(DWORD));
  177. // If the texture falls outside the current 8Mb window
  178. // then adjust the AGP base address
  179. if (lSurfaceOffset < ppdev->dwGARTLin ||
  180. ((lSurfaceOffset + lTextureSize - ppdev->dwGARTLin) >= 0x800000))
  181. {
  182. UINT_PTR dwNewGARTOffset = lSurfaceOffset;
  183. bChanged = TRUE;
  184. ppdev->dwGARTDev = ppdev->dwGARTDevBase + dwNewGARTOffset;
  185. ppdev->dwGARTLin = ppdev->dwGARTLinBase + dwNewGARTOffset;
  186. DBG_D3D((4,"Relocated AGP TextureBase Address "
  187. "to : 0x%x (Base: 0x%x)",
  188. ppdev->dwGARTDev, ppdev->dwGARTDevBase));
  189. }
  190. //If the texture is in a different place relative to the base of
  191. // AGP memory that we are using then update it
  192. if (pTexture->dwGARTDevLast != ppdev->dwGARTDev)
  193. {
  194. pTexture->dwGARTDevLast = ppdev->dwGARTDev;
  195. StorePermediaLODLevel(ppdev, pTexture, pSurf, 0);
  196. }
  197. DBG_D3D((10,"Exiting CheckAGPTexturePage"));
  198. return bChanged;
  199. }
  200. #endif
  201. //@@END_DDKSPLIT
  202. //-----------------------------------------------------------------------------
  203. //
  204. // void DisableTexturePermedia
  205. //
  206. // Disable texturing in P2
  207. //
  208. //-----------------------------------------------------------------------------
  209. void
  210. DisableTexturePermedia(PERMEDIA_D3DCONTEXT* pContext)
  211. {
  212. DWORD* pFlags = &pContext->Hdr.Flags;
  213. PERMEDIA_D3DTEXTURE* pTexture = NULL;
  214. __P2RegsSoftwareCopy* pSoftPermedia = &pContext->Hdr.SoftCopyP2Regs;
  215. PERMEDIA_DEFS(pContext->ppdev);
  216. DBG_D3D((10,"Entering DisableTexturePermedia"));
  217. pContext->FakeBlendNum &= ~FAKE_ALPHABLEND_MODULATE;
  218. // The textures have been turned off, so...
  219. ASSERTDD(pContext->CurrentTextureHandle == 0,
  220. "DisableTexturePermedia expected zero texture handle");
  221. DBG_D3D((4, "Disabling Texturing"));
  222. RESERVEDMAPTR(8);
  223. // Turn off texture address generation
  224. pSoftPermedia->TextureAddressMode.Enable = 0;
  225. COPY_PERMEDIA_DATA(TextureAddressMode, pSoftPermedia->TextureAddressMode);
  226. // Turn off texture reads
  227. pSoftPermedia->TextureReadMode.Enable = 0;
  228. COPY_PERMEDIA_DATA(TextureReadMode, pSoftPermedia->TextureReadMode);
  229. // Turn off textures
  230. pSoftPermedia->TextureColorMode.TextureEnable = 0;
  231. COPY_PERMEDIA_DATA(TextureColorMode, pSoftPermedia->TextureColorMode);
  232. // Set the texture base address to 0
  233. // (turning off the 'AGP' bit in the process)
  234. // Also stop TexelLUTTransfer messages
  235. SEND_PERMEDIA_DATA(TextureBaseAddress, 0);
  236. SEND_PERMEDIA_DATA(TexelLUTTransfer, __PERMEDIA_DISABLE);
  237. // Set current texture to 0
  238. pContext->CurrentTextureHandle = 0;
  239. *pFlags &= ~CTXT_HAS_TEXTURE_ENABLED;
  240. RENDER_TEXTURE_DISABLE(pContext->RenderCommand);
  241. // If textures were in copy mode, we may have fiddled with the DDA,
  242. // to improve performance.
  243. if ((unsigned int)pSoftPermedia->TextureColorMode.ApplicationMode ==
  244. _P2_TEXTURE_COPY)
  245. {
  246. if (*pFlags & CTXT_HAS_GOURAUD_ENABLED)
  247. {
  248. pSoftPermedia->DeltaMode.SmoothShadingEnable = 1;
  249. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  250. pSoftPermedia->ColorDDAMode.UnitEnable = 1;
  251. // Smooth shade, DDA Enable
  252. COPY_PERMEDIA_DATA(ColorDDAMode, pSoftPermedia->ColorDDAMode);
  253. }
  254. else
  255. {
  256. pSoftPermedia->DeltaMode.SmoothShadingEnable = 0;
  257. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  258. pSoftPermedia->ColorDDAMode.UnitEnable = 1;
  259. // Flat shade, DDA Enable
  260. COPY_PERMEDIA_DATA(ColorDDAMode, pSoftPermedia->ColorDDAMode);
  261. }
  262. }
  263. if (pContext->bCanChromaKey == TRUE)
  264. {
  265. // Turn off Chroma Keying
  266. pSoftPermedia->YUVMode.TestMode = PM_YUVMODE_CHROMATEST_DISABLE;
  267. pSoftPermedia->YUVMode.Enable = __PERMEDIA_DISABLE;
  268. COPY_PERMEDIA_DATA(YUVMode, pSoftPermedia->YUVMode);
  269. pContext->bCanChromaKey = FALSE;
  270. }
  271. COMMITDMAPTR();
  272. DBG_D3D((10,"Exiting DisableTexturePermedia"));
  273. return;
  274. } // DisableTexturePermedia
  275. //-----------------------------------------------------------------------------
  276. //
  277. // void Convert_Chroma_2_8888ARGB
  278. //
  279. // Conversion of a chroma value into 32bpp ARGB
  280. //
  281. //-----------------------------------------------------------------------------
  282. void
  283. Convert_Chroma_2_8888ARGB(DWORD *pdwLowerBound, DWORD *pdwUpperBound,
  284. DWORD dwRedMask, DWORD dwAlphaMask, DWORD dwPixelSize)
  285. {
  286. DBG_D3D((10,"Entering Convert_Chroma_2_8888ARGB"));
  287. switch (dwPixelSize) {
  288. case __PERMEDIA_8BITPIXEL:
  289. if (dwRedMask == 0xE0)
  290. {
  291. // Never any alpha
  292. *pdwLowerBound =
  293. CHROMA_LOWER_ALPHA(FORMAT_332_32BIT_BGR(*pdwLowerBound));
  294. *pdwUpperBound =
  295. CHROMA_UPPER_ALPHA(FORMAT_332_32BIT_BGR(*pdwUpperBound));
  296. }
  297. else
  298. {
  299. *pdwLowerBound = FORMAT_2321_32BIT_BGR(*pdwLowerBound);
  300. *pdwUpperBound = FORMAT_2321_32BIT_BGR(*pdwUpperBound);
  301. if (!dwAlphaMask)
  302. {
  303. *pdwLowerBound = CHROMA_LOWER_ALPHA(*pdwLowerBound);
  304. *pdwUpperBound = CHROMA_UPPER_ALPHA(*pdwUpperBound);
  305. }
  306. }
  307. break;
  308. case __PERMEDIA_16BITPIXEL:
  309. switch (dwRedMask)
  310. {
  311. case 0xf00:
  312. *pdwLowerBound = (FORMAT_4444_32BIT_BGR(*pdwLowerBound));
  313. *pdwUpperBound = (FORMAT_4444_32BIT_BGR(*pdwUpperBound));
  314. if (!dwAlphaMask)
  315. {
  316. *pdwLowerBound = CHROMA_LOWER_ALPHA(*pdwLowerBound);
  317. *pdwUpperBound = CHROMA_UPPER_ALPHA(*pdwUpperBound);
  318. }
  319. // Acount for the internal 8888 -> 4444 translation
  320. // which causes bilinear chroma keying to fail in
  321. // some cases
  322. *pdwLowerBound = *pdwLowerBound & 0xF0F0F0F0;
  323. *pdwUpperBound = *pdwUpperBound | 0x0F0F0F0F;
  324. break;
  325. case 0x7c00:
  326. *pdwLowerBound = FORMAT_5551_32BIT_BGR(*pdwLowerBound);
  327. *pdwUpperBound = FORMAT_5551_32BIT_BGR(*pdwUpperBound);
  328. if (!dwAlphaMask)
  329. {
  330. *pdwLowerBound = CHROMA_LOWER_ALPHA(*pdwLowerBound);
  331. *pdwUpperBound = CHROMA_UPPER_ALPHA(*pdwUpperBound);
  332. }
  333. // Acount for the internal 8888 -> 5551 translation
  334. // which causes bilinear chroma keying to fail in
  335. // some cases
  336. *pdwLowerBound = *pdwLowerBound & 0x80F8F8F8;
  337. *pdwUpperBound = *pdwUpperBound | 0x7F070707;
  338. break;
  339. default:
  340. // Always supply full range of alpha values to ensure test
  341. // is done
  342. *pdwLowerBound =
  343. CHROMA_LOWER_ALPHA(FORMAT_565_32BIT_BGR(*pdwLowerBound));
  344. *pdwUpperBound =
  345. CHROMA_UPPER_ALPHA(FORMAT_565_32BIT_BGR(*pdwUpperBound));
  346. if (!dwAlphaMask)
  347. {
  348. *pdwLowerBound = CHROMA_LOWER_ALPHA(*pdwLowerBound);
  349. *pdwUpperBound = CHROMA_UPPER_ALPHA(*pdwUpperBound);
  350. }
  351. // Acount for the internal 888 -> 565 translation
  352. // which causes bilinear chroma keying to fail in
  353. // some cases
  354. *pdwLowerBound = *pdwLowerBound & 0xF8F8FCF8;
  355. *pdwUpperBound = *pdwUpperBound | 0x07070307;
  356. break;
  357. }
  358. break;
  359. case __PERMEDIA_24BITPIXEL:
  360. case __PERMEDIA_32BITPIXEL:
  361. *pdwLowerBound = FORMAT_8888_32BIT_BGR(*pdwLowerBound);
  362. *pdwUpperBound = FORMAT_8888_32BIT_BGR(*pdwUpperBound);
  363. // If the surface isn't alpha'd then set a valid
  364. // range of alpha to catch all cases.
  365. if (!dwAlphaMask)
  366. {
  367. *pdwLowerBound = CHROMA_LOWER_ALPHA(*pdwLowerBound);
  368. *pdwUpperBound = CHROMA_UPPER_ALPHA(*pdwUpperBound);
  369. }
  370. break;
  371. }
  372. DBG_D3D((10,"Exiting Convert_Chroma_2_8888ARGB"));
  373. } // Convert_Chroma_2_8888ARGB
  374. //-----------------------------------------------------------------------------
  375. //
  376. // void EnableTexturePermedia
  377. //
  378. // Enable and setup texturing for pContext->CurrentTextureHandle
  379. //
  380. //-----------------------------------------------------------------------------
  381. void
  382. EnableTexturePermedia(PERMEDIA_D3DCONTEXT* pContext)
  383. {
  384. DWORD* pFlags = &pContext->Hdr.Flags;
  385. PERMEDIA_D3DTEXTURE* pTexture = NULL;
  386. __P2RegsSoftwareCopy* pSoftPermedia = &pContext->Hdr.SoftCopyP2Regs;
  387. PERMEDIA_DEFS(pContext->ppdev);
  388. PERMEDIA_D3DPALETTE* pPalette=NULL;
  389. LPPALETTEENTRY lpColorTable=NULL; // array of palette entries
  390. PPDev ppdev = pContext->ppdev;
  391. DBG_D3D((10,"Entering EnableTexturePermedia %d",
  392. pContext->CurrentTextureHandle));
  393. pContext->FakeBlendNum &= ~FAKE_ALPHABLEND_MODULATE;
  394. // A texture has been turned on so ...
  395. ASSERTDD(pContext->CurrentTextureHandle != 0,
  396. "EnableTexturePermedia expected non zero texture handle");
  397. // We must be texturing so...
  398. pTexture = TextureHandleToPtr(pContext->CurrentTextureHandle, pContext);
  399. if (CHECK_D3DSURFACE_VALIDITY(pTexture))
  400. {
  401. PermediaSurfaceData* pPrivateData;
  402. DWORD cop = pContext->TssStates[D3DTSS_COLOROP];
  403. DWORD ca1 = pContext->TssStates[D3DTSS_COLORARG1];
  404. DWORD ca2 = pContext->TssStates[D3DTSS_COLORARG2];
  405. DWORD aop = pContext->TssStates[D3DTSS_ALPHAOP];
  406. DWORD aa1 = pContext->TssStates[D3DTSS_ALPHAARG1];
  407. // Current is the same as diffuse in stage 0
  408. if (ca2 == D3DTA_CURRENT)
  409. ca2 = D3DTA_DIFFUSE;
  410. pPrivateData = pTexture->pTextureSurface;
  411. if (!CHECK_P2_SURFACEDATA_VALIDITY(pPrivateData))
  412. {
  413. DBG_D3D((0,"EnableTexturePermedia get invalid pPrivateData=0x%x"
  414. " from SurfaceHandle=%d", pPrivateData,
  415. pContext->CurrentTextureHandle));
  416. pContext->CurrentTextureHandle = 0;
  417. // If the texture is bad, let's ensure it's marked as such.
  418. pTexture->MagicNo = TC_MAGIC_DISABLE;
  419. goto Exit_EnableTexturePermedia;
  420. }
  421. if (pTexture->dwCaps2 & DDSCAPS2_TEXTUREMANAGE)
  422. {
  423. if (NULL==pPrivateData->fpVidMem)
  424. {
  425. TextureCacheManagerAllocNode(pContext,pTexture);
  426. if (NULL==pPrivateData->fpVidMem)
  427. {
  428. DBG_D3D((0,"EnableTexturePermedia unable to allocate memory from heap"));
  429. pContext->CurrentTextureHandle = 0;
  430. goto Exit_EnableTexturePermedia;
  431. }
  432. pPrivateData->dwFlags |= P2_SURFACE_NEEDUPDATE;
  433. }
  434. TextureCacheManagerTimeStamp(pContext->pTextureManager,pTexture);
  435. if (pPrivateData->dwFlags & P2_SURFACE_NEEDUPDATE)
  436. {
  437. RECTL rect;
  438. rect.left=rect.top=0;
  439. rect.right=pTexture->wWidth;
  440. rect.bottom=pTexture->wHeight;
  441. // texture download
  442. // Switch to DirectDraw context
  443. pPrivateData->dwFlags &= ~P2_SURFACE_NEEDUPDATE;
  444. // .. Convert it to Pixels
  445. pTexture->MipLevels[0].PixelOffset =
  446. (DWORD)(pPrivateData->fpVidMem);
  447. switch(pTexture->pTextureSurface->SurfaceFormat.PixelSize)
  448. {
  449. case __PERMEDIA_4BITPIXEL:
  450. pTexture->MipLevels[0].PixelOffset <<= 1;
  451. break;
  452. case __PERMEDIA_8BITPIXEL: /* No Change*/
  453. break;
  454. case __PERMEDIA_16BITPIXEL:
  455. pTexture->MipLevels[0].PixelOffset >>= 1;
  456. break;
  457. case __PERMEDIA_24BITPIXEL:
  458. pTexture->MipLevels[0].PixelOffset /= 3;
  459. break;
  460. case __PERMEDIA_32BITPIXEL:
  461. pTexture->MipLevels[0].PixelOffset >>= 2;
  462. break;
  463. default:
  464. ASSERTDD(0,"Invalid Texture Pixel Size!");
  465. pTexture->MipLevels[0].PixelOffset >>= 1;
  466. break;
  467. }
  468. PermediaPatchedTextureDownload(pContext->ppdev,
  469. pPrivateData,
  470. pTexture->fpVidMem,
  471. pTexture->lPitch,
  472. &rect,
  473. pPrivateData->fpVidMem,
  474. pTexture->lPitch,
  475. &rect);
  476. //need to restore following registers
  477. RESERVEDMAPTR(7);
  478. SEND_PERMEDIA_DATA(FBReadPixel, pSoftPermedia->FBReadPixel);
  479. COPY_PERMEDIA_DATA(FBReadMode, pSoftPermedia->FBReadMode);
  480. SEND_PERMEDIA_DATA(FBPixelOffset, pContext->PixelOffset);
  481. SEND_PERMEDIA_DATA(FBWindowBase,0);
  482. COPY_PERMEDIA_DATA(Window, pSoftPermedia->Window);
  483. COPY_PERMEDIA_DATA(AlphaBlendMode, pSoftPermedia->AlphaBlendMode);
  484. COPY_PERMEDIA_DATA(DitherMode, pSoftPermedia->DitherMode);
  485. COMMITDMAPTR();
  486. DBG_D3D((10, "Copy from %08lx to %08lx w=%08lx h=%08lx p=%08lx b=%08lx",
  487. pTexture->fpVidMem,pPrivateData->fpVidMem,pTexture->wWidth,
  488. pTexture->wHeight,pTexture->lPitch,pTexture->dwRGBBitCount));
  489. }
  490. }
  491. // If it is a palette indexed texture, we simply follow the chain
  492. // down from the surface to it's palette and pull out the LUT values
  493. // from the PALETTEENTRY's in the palette.
  494. if (pPrivateData->SurfaceFormat.Format == PERMEDIA_8BIT_PALETTEINDEX ||
  495. pPrivateData->SurfaceFormat.Format == PERMEDIA_4BIT_PALETTEINDEX)
  496. {
  497. pPalette =
  498. PaletteHandleToPtr(pTexture->dwPaletteHandle,pContext);
  499. if (NULL != pPalette)
  500. {
  501. //some apps are not setting their alpha correctly with palette
  502. //then it's up to palette to tell us
  503. pPrivateData->SurfaceFormat.bAlpha =
  504. pPalette->dwFlags & DDRAWIPAL_ALPHA;
  505. }
  506. }
  507. if ((ca2 == D3DTA_DIFFUSE && ca1 == D3DTA_TEXTURE) &&
  508. cop == D3DTOP_MODULATE &&
  509. (aa1 == D3DTA_TEXTURE && aop == D3DTOP_LEGACY_ALPHAOVR))
  510. {
  511. // if this is legacy modulation then we take the texture alpha
  512. // only if the texure format has it
  513. if (pPrivateData->SurfaceFormat.bAlpha)
  514. pContext->FakeBlendNum |= FAKE_ALPHABLEND_MODULATE;
  515. }
  516. else if ((ca2 == D3DTA_DIFFUSE && ca1 == D3DTA_TEXTURE) &&
  517. cop == D3DTOP_MODULATE &&
  518. (aa1 == D3DTA_TEXTURE && aop == D3DTOP_SELECTARG1))
  519. {
  520. // if this is DX6 modulation then we take the texture alpha
  521. // no matter what ( it will be xFF if it doesn't exist)
  522. pContext->FakeBlendNum |= FAKE_ALPHABLEND_MODULATE;
  523. }
  524. // Enable Texture Address calculation
  525. pSoftPermedia->TextureAddressMode.Enable = 1;
  526. // Enable Textures
  527. pSoftPermedia->TextureColorMode.TextureEnable = 1;
  528. if (*pFlags & CTXT_HAS_SPECULAR_ENABLED)
  529. {
  530. pSoftPermedia->DeltaMode.SpecularTextureEnable = 1;
  531. pSoftPermedia->TextureColorMode.KsDDA = 1;
  532. pSoftPermedia->TextureColorMode.ApplicationMode |=
  533. _P2_TEXTURE_SPECULAR;
  534. }
  535. else
  536. {
  537. pSoftPermedia->DeltaMode.SpecularTextureEnable = 0;
  538. pSoftPermedia->TextureColorMode.KsDDA = 0;
  539. pSoftPermedia->TextureColorMode.ApplicationMode &=
  540. ~_P2_TEXTURE_SPECULAR;
  541. }
  542. // reserve here for all cases in this function!!
  543. RESERVEDMAPTR(272);
  544. COPY_PERMEDIA_DATA(DeltaMode, pSoftPermedia->DeltaMode);
  545. // Set Partial products for texture (assume no mipmapping).
  546. pSoftPermedia->TextureMapFormat.PackedPP =
  547. pTexture->MipLevels[0].ulPackedPP;
  548. pSoftPermedia->TextureMapFormat.TexelSize =
  549. pPrivateData->SurfaceFormat.PixelSize;
  550. if (pPrivateData->dwFlags & P2_ISPATCHED)
  551. {
  552. DBG_D3D((4," Enabling Patching for this texture"));
  553. pSoftPermedia->TextureMapFormat.SubPatchMode = 1;
  554. }
  555. else
  556. {
  557. pSoftPermedia->TextureMapFormat.SubPatchMode = 0;
  558. }
  559. DBG_D3D((4, " Texel Size: 0x%x",
  560. pPrivateData->SurfaceFormat.PixelSize));
  561. // Set texture size
  562. DBG_D3D((4," Texture Width: 0x%x",
  563. pTexture->MipLevels[0].logWidth));
  564. DBG_D3D((4," Texture Height: 0x%x",
  565. pTexture->MipLevels[0].logHeight));
  566. pSoftPermedia->TextureReadMode.Width =
  567. pTexture->MipLevels[0].logWidth;
  568. pSoftPermedia->TextureReadMode.Height =
  569. pTexture->MipLevels[0].logHeight;
  570. pSoftPermedia->TextureReadMode.Enable = 1;
  571. pContext->DeltaWidthScale = (float)pTexture->wWidth * (1 / 2048.0f);
  572. pContext->DeltaHeightScale = (float)pTexture->wHeight * (1 / 2048.0f);
  573. pContext->MaxTextureXf = (float)(2048 / pTexture->wWidth);
  574. pContext->MaxTextureYf = (float)(2048 / pTexture->wHeight);
  575. myFtoui(&pContext->MaxTextureXi, pContext->MaxTextureXf);
  576. pContext->MaxTextureXi -= 1;
  577. myFtoui(&pContext->MaxTextureYi, pContext->MaxTextureYf);
  578. pContext->MaxTextureYi -= 1;
  579. *pFlags |= CTXT_HAS_TEXTURE_ENABLED;
  580. RENDER_TEXTURE_ENABLE(pContext->RenderCommand);
  581. DBG_D3D((4," Texture Format: 0x%x",
  582. pPrivateData->SurfaceFormat.Format));
  583. DBG_D3D((4," Texture Format Extension: 0x%x",
  584. pPrivateData->SurfaceFormat.FormatExtension));
  585. pSoftPermedia->TextureDataFormat.TextureFormat =
  586. pPrivateData->SurfaceFormat.Format;
  587. pSoftPermedia->TextureDataFormat.TextureFormatExtension =
  588. pPrivateData->SurfaceFormat.FormatExtension;
  589. if (pPrivateData->SurfaceFormat.bAlpha)
  590. {
  591. pSoftPermedia->TextureDataFormat.NoAlphaBuffer = 0;
  592. }
  593. else
  594. {
  595. pSoftPermedia->TextureDataFormat.NoAlphaBuffer = 1;
  596. }
  597. // If we are copying textures, there is no need for colour data
  598. // to be generated, so we turn off the DDA
  599. if (((unsigned int)pSoftPermedia->TextureColorMode.ApplicationMode) ==
  600. _P2_TEXTURE_COPY)
  601. {
  602. pSoftPermedia->ColorDDAMode.UnitEnable = 0;
  603. DBG_D3D((4, " Disabling DDA"));
  604. }
  605. else
  606. {
  607. pSoftPermedia->ColorDDAMode.UnitEnable = 1;
  608. DBG_D3D((4, " Enabling DDA"));
  609. }
  610. // Load the texture base address BEFORE the TexelLUTTransfer message
  611. // to ensure we load the LUT from the right sort of memory (AGP or not)
  612. // Always set the base address at the root texture (not the miplevels
  613. // if there are any)
  614. DBG_D3D((4, "Setting texture base address to 0x%08X",
  615. pTexture->MipLevels[0].PixelOffset));
  616. SEND_PERMEDIA_DATA(TextureBaseAddress,
  617. pTexture->MipLevels[0].PixelOffset);
  618. // If it is a palette indexed texture, we simply follow the chain
  619. // down from the surface to it's palette and pull out the LUT values
  620. // from the PALETTEENTRY's in the palette.
  621. if (pPrivateData->SurfaceFormat.Format == PERMEDIA_8BIT_PALETTEINDEX)
  622. {
  623. if (NULL != pPalette)
  624. {
  625. int i;
  626. lpColorTable = pPalette->ColorTable;
  627. if (pPalette->dwFlags & DDRAWIPAL_ALPHA)
  628. {
  629. for (i = 0; i < 256; i++)
  630. {
  631. SEND_PERMEDIA_DATA(TexelLUTData, *(DWORD*)lpColorTable);
  632. lpColorTable++;
  633. }
  634. }
  635. else
  636. {
  637. for (i = 0; i < 256; i++)
  638. {
  639. SEND_PERMEDIA_DATA(TexelLUTData,
  640. CHROMA_UPPER_ALPHA(*(DWORD*)lpColorTable));
  641. lpColorTable++;
  642. }
  643. }
  644. SEND_PERMEDIA_DATA(TexelLUTMode, __PERMEDIA_ENABLE);
  645. DBG_D3D((4,"Texel LUT pPalette->dwFlags=%08lx bAlpha=%d",
  646. pPalette->dwFlags,pPrivateData->SurfaceFormat.bAlpha));
  647. // Must reset the LUT index on Permedia P2
  648. SEND_PERMEDIA_DATA(TexelLUTIndex, 0);
  649. }
  650. else
  651. {
  652. DBG_D3D((0, "NULL == pPalette in EnableTexturePermedia"
  653. "dwPaletteHandle=%08lx dwSurfaceHandle=%08lx",
  654. pTexture->dwPaletteHandle,
  655. pContext->CurrentTextureHandle));
  656. }
  657. }
  658. else if (pPrivateData->SurfaceFormat.Format ==
  659. PERMEDIA_4BIT_PALETTEINDEX)
  660. {
  661. if (NULL != pPalette)
  662. {
  663. int i;
  664. lpColorTable = pPalette->ColorTable;
  665. SEND_PERMEDIA_DATA(TexelLUTMode, __PERMEDIA_ENABLE);
  666. if (pPalette->dwFlags & DDRAWIPAL_ALPHA)
  667. {
  668. for (i = 0; i < 16; i++)
  669. {
  670. SEND_PERMEDIA_DATA_OFFSET(TexelLUT0,
  671. *(DWORD*)lpColorTable,i);
  672. lpColorTable++;
  673. }
  674. }
  675. else
  676. {
  677. for (i = 0; i < 16; i++)
  678. {
  679. SEND_PERMEDIA_DATA_OFFSET(TexelLUT0,
  680. CHROMA_UPPER_ALPHA(*(DWORD*)lpColorTable),i);
  681. lpColorTable++;
  682. }
  683. }
  684. // Must reset the LUT index on Permedia P2
  685. SEND_PERMEDIA_DATA(TexelLUTIndex, 0);
  686. SEND_PERMEDIA_DATA(TexelLUTTransfer, __PERMEDIA_DISABLE);
  687. }
  688. else
  689. {
  690. DBG_D3D((0, "NULL == pPalette in EnableTexturePermedia"
  691. "dwPaletteHandle=%08lx dwSurfaceHandle=%08lx",
  692. pTexture->dwPaletteHandle,
  693. pContext->CurrentTextureHandle));
  694. }
  695. }
  696. else
  697. {
  698. // Not palette indexed
  699. SEND_PERMEDIA_DATA(TexelLUTMode, __PERMEDIA_DISABLE);
  700. }
  701. if ((pTexture->dwFlags & DDRAWISURF_HASCKEYSRCBLT)
  702. && (pContext->RenderStates[D3DRENDERSTATE_COLORKEYENABLE]))
  703. {
  704. DWORD LowerBound = pTexture->dwKeyLow;
  705. DWORD UpperBound = pTexture->dwKeyHigh;
  706. DWORD dwLowIndexColor;
  707. pContext->bCanChromaKey = TRUE;
  708. DBG_D3D((4," Can Chroma Key the texture"));
  709. // Enable Chroma keying for the texture
  710. // ..and set the correct colour
  711. // Evaluate the new chroma key value. Shouldn't be too expensive,
  712. // as it is only bit shifts and a couple of tests.
  713. // We also change only when the texture map has changed.
  714. DBG_D3D((4, "dwColorSpaceLow = 0x%08X", LowerBound));
  715. DBG_D3D((4, "dwColorSpaceHigh = 0x%08X", UpperBound));
  716. if (NULL != pPalette)
  717. {
  718. if (pPrivateData->SurfaceFormat.Format ==
  719. PERMEDIA_4BIT_PALETTEINDEX)
  720. {
  721. LowerBound &= 0x0F;
  722. }
  723. else
  724. {
  725. LowerBound &= 0xFF;
  726. }
  727. lpColorTable = pPalette->ColorTable;
  728. // ChromaKeying for 4/8 Bit textures is done on the looked up
  729. // color, not the index. This means using a range is
  730. // meaningless and we have to lookup the color from the
  731. // palette. Make sure the user doesn't force us to access
  732. // invalid memory.
  733. dwLowIndexColor = *(DWORD*)(&lpColorTable[LowerBound]);
  734. if (pPalette->dwFlags & DDRAWIPAL_ALPHA)
  735. {
  736. LowerBound = UpperBound = dwLowIndexColor;
  737. }
  738. else
  739. {
  740. LowerBound = CHROMA_LOWER_ALPHA(dwLowIndexColor);
  741. UpperBound = CHROMA_UPPER_ALPHA(dwLowIndexColor);
  742. }
  743. DBG_D3D((4,"PaletteHandle=%08lx Lower=%08lx ChromaColor=%08lx"
  744. "lpColorTable=%08lx dwFlags=%08lx",
  745. pTexture->dwPaletteHandle, LowerBound, dwLowIndexColor,
  746. lpColorTable, pPalette->dwFlags));
  747. }
  748. else
  749. Convert_Chroma_2_8888ARGB(&LowerBound,
  750. &UpperBound,
  751. pPrivateData->SurfaceFormat.RedMask,
  752. pPrivateData->SurfaceFormat.AlphaMask,
  753. pPrivateData->SurfaceFormat.PixelSize);
  754. DBG_D3D((4,"LowerBound Selected: 0x%x", LowerBound));
  755. DBG_D3D((4,"UpperBound Selected: 0x%x", UpperBound));
  756. // If it's a P2 we can use alpha mapping to
  757. // improve bilinear chroma keying.
  758. if (0/*(unsigned int)pSoftPermedia->TextureReadMode.FilterMode == 1*/)
  759. {
  760. pSoftPermedia->TextureDataFormat.AlphaMap =
  761. PM_TEXDATAFORMAT_ALPHAMAP_EXCLUDE;
  762. pSoftPermedia->TextureDataFormat.NoAlphaBuffer = 1;
  763. SEND_PERMEDIA_DATA(AlphaMapUpperBound, UpperBound);
  764. SEND_PERMEDIA_DATA(AlphaMapLowerBound, LowerBound);
  765. SEND_PERMEDIA_DATA(ChromaUpperBound, 0xFFFFFFFF);
  766. SEND_PERMEDIA_DATA(ChromaLowerBound, 0xFF000000);
  767. pSoftPermedia->YUVMode.TestMode =
  768. PM_YUVMODE_CHROMATEST_PASSWITHIN;
  769. }
  770. else
  771. {
  772. pSoftPermedia->TextureDataFormat.AlphaMap =
  773. PM_TEXDATAFORMAT_ALPHAMAP_DISABLE;
  774. SEND_PERMEDIA_DATA(ChromaUpperBound, UpperBound);
  775. SEND_PERMEDIA_DATA(ChromaLowerBound, LowerBound);
  776. pSoftPermedia->YUVMode.TestMode =
  777. PM_YUVMODE_CHROMATEST_FAILWITHIN;
  778. }
  779. }
  780. else
  781. {
  782. DBG_D3D((2," Can't Chroma Key the texture"));
  783. pContext->bCanChromaKey = FALSE;
  784. pSoftPermedia->TextureDataFormat.AlphaMap = __PERMEDIA_DISABLE;
  785. pSoftPermedia->YUVMode.TestMode = PM_YUVMODE_CHROMATEST_DISABLE;
  786. }
  787. // Restore the filter mode from the mag filter.
  788. if (pContext->bMagFilter)
  789. {
  790. pSoftPermedia->TextureReadMode.FilterMode = 1;
  791. }
  792. else
  793. {
  794. pSoftPermedia->TextureReadMode.FilterMode = 0;
  795. }
  796. // If the texture is a YUV texture we need to change the color order
  797. // of the surface and turn on the YUV->RGB conversoin
  798. if (pPrivateData->SurfaceFormat.Format == PERMEDIA_YUV422)
  799. {
  800. pSoftPermedia->YUVMode.Enable = __PERMEDIA_ENABLE;
  801. pSoftPermedia->TextureDataFormat.ColorOrder = INV_COLOR_MODE;
  802. }
  803. else
  804. {
  805. pSoftPermedia->YUVMode.Enable = __PERMEDIA_DISABLE;
  806. pSoftPermedia->TextureDataFormat.ColorOrder = COLOR_MODE;
  807. }
  808. // Send the Commands at the end (except the texture base address!!)
  809. COPY_PERMEDIA_DATA(TextureReadMode, pSoftPermedia->TextureReadMode);
  810. COPY_PERMEDIA_DATA(TextureDataFormat, pSoftPermedia->TextureDataFormat);
  811. COPY_PERMEDIA_DATA(ColorDDAMode, pSoftPermedia->ColorDDAMode);
  812. COPY_PERMEDIA_DATA(TextureMapFormat, pSoftPermedia->TextureMapFormat);
  813. COPY_PERMEDIA_DATA(TextureColorMode, pSoftPermedia->TextureColorMode);
  814. COPY_PERMEDIA_DATA(YUVMode, pSoftPermedia->YUVMode);
  815. COPY_PERMEDIA_DATA(TextureAddressMode,
  816. pSoftPermedia->TextureAddressMode);
  817. COMMITDMAPTR();
  818. FLUSHDMA();
  819. }
  820. else
  821. {
  822. DBG_D3D((0,"Invalid Texture handle (%d)!, doing nothing",
  823. pContext->CurrentTextureHandle));
  824. pContext->CurrentTextureHandle = 0;
  825. // If the texture is bad, let's ensure it's marked as such.
  826. // But only if the texture is actually there!!
  827. if (pTexture)
  828. pTexture->MagicNo = TC_MAGIC_DISABLE;
  829. }
  830. Exit_EnableTexturePermedia:
  831. DBG_D3D((10,"Exiting EnableTexturePermedia"));
  832. } // EnableTexturePermedia
  833. //-----------------------------------------------------------------------------
  834. //
  835. // void: __PermediaDisableUnits
  836. //
  837. // Disables all the mode registers to give us a clean start.
  838. //
  839. //-----------------------------------------------------------------------------
  840. void
  841. __PermediaDisableUnits(PERMEDIA_D3DCONTEXT* pContext)
  842. {
  843. PERMEDIA_DEFS(pContext->ppdev);
  844. DBG_D3D((10,"Entering __PermediaDisableUnits"));
  845. RESERVEDMAPTR(28);
  846. SEND_PERMEDIA_DATA(RasterizerMode, __PERMEDIA_DISABLE);
  847. SEND_PERMEDIA_DATA(AreaStippleMode, __PERMEDIA_DISABLE);
  848. SEND_PERMEDIA_DATA(ScissorMode, __PERMEDIA_DISABLE);
  849. SEND_PERMEDIA_DATA(ColorDDAMode, __PERMEDIA_DISABLE);
  850. SEND_PERMEDIA_DATA(FogMode, __PERMEDIA_DISABLE);
  851. SEND_PERMEDIA_DATA(LBReadMode, __PERMEDIA_DISABLE);
  852. SEND_PERMEDIA_DATA(Window, __PERMEDIA_DISABLE);
  853. SEND_PERMEDIA_DATA(StencilMode, __PERMEDIA_DISABLE);
  854. SEND_PERMEDIA_DATA(DepthMode, __PERMEDIA_DISABLE);
  855. SEND_PERMEDIA_DATA(LBWriteMode, __PERMEDIA_DISABLE);
  856. SEND_PERMEDIA_DATA(FBReadMode, __PERMEDIA_DISABLE);
  857. SEND_PERMEDIA_DATA(DitherMode, __PERMEDIA_DISABLE);
  858. SEND_PERMEDIA_DATA(AlphaBlendMode, __PERMEDIA_DISABLE);
  859. SEND_PERMEDIA_DATA(LogicalOpMode, __PERMEDIA_DISABLE);
  860. SEND_PERMEDIA_DATA(FBWriteMode, __PERMEDIA_DISABLE);
  861. SEND_PERMEDIA_DATA(StatisticMode, __PERMEDIA_DISABLE);
  862. SEND_PERMEDIA_DATA(FilterMode, __PERMEDIA_DISABLE);
  863. SEND_PERMEDIA_DATA(FBSourceData, __PERMEDIA_DISABLE);
  864. SEND_PERMEDIA_DATA(LBWriteFormat, __PERMEDIA_DISABLE);
  865. SEND_PERMEDIA_DATA(TextureReadMode, __PERMEDIA_DISABLE);
  866. SEND_PERMEDIA_DATA(TextureMapFormat, __PERMEDIA_DISABLE);
  867. SEND_PERMEDIA_DATA(TextureDataFormat, __PERMEDIA_DISABLE);
  868. SEND_PERMEDIA_DATA(TexelLUTMode, __PERMEDIA_DISABLE);
  869. SEND_PERMEDIA_DATA(TextureColorMode, __PERMEDIA_DISABLE);
  870. SEND_PERMEDIA_DATA(AStart, PM_BYTE_COLOR(0xFF));
  871. // Ensure AGP bit not set.
  872. SEND_PERMEDIA_DATA(TextureBaseAddress, 0);
  873. SEND_PERMEDIA_DATA(TexelLUTIndex, 0);
  874. SEND_PERMEDIA_DATA(TexelLUTTransfer, __PERMEDIA_DISABLE);
  875. COMMITDMAPTR();
  876. FLUSHDMA();
  877. DBG_D3D((10,"Exiting __PermediaDisableUnits"));
  878. } // __PermediaDisableUnits
  879. #ifdef DBG
  880. //-----------------------------------------------------------------------------
  881. //
  882. // void DumpTexture
  883. //
  884. // Debug dump of texture information
  885. //
  886. //-----------------------------------------------------------------------------
  887. void
  888. DumpTexture(PPDev ppdev,
  889. PERMEDIA_D3DTEXTURE* pTexture,
  890. DDPIXELFORMAT* pPixelFormat)
  891. {
  892. DBG_D3D((4, "\n** Texture Dump:"));
  893. DBG_D3D((4," Texture Width: %d", pTexture->wWidth));
  894. DBG_D3D((4," Texture Height: %d", pTexture->wHeight));
  895. if (NULL != pTexture->pTextureSurface)
  896. {
  897. DBG_D3D((4," LogWidth: %d",
  898. pTexture->MipLevels[0].logWidth));
  899. DBG_D3D((4," LogHeight: %d",
  900. pTexture->MipLevels[0].logHeight));
  901. DBG_D3D((4," PackedPP0: 0x%x",
  902. pTexture->pTextureSurface->ulPackedPP));
  903. }
  904. DBG_D3D((4," Pixel Offset of Texture (PERMEDIA Chip): 0x%x",
  905. pTexture->MipLevels[0].PixelOffset));
  906. // Show texture format
  907. if (pPixelFormat->dwRGBAlphaBitMask == 0xf000)
  908. {
  909. DBG_D3D((4," Texture is 4:4:4:4"));
  910. }
  911. else if (pPixelFormat->dwRBitMask == 0xff0000)
  912. {
  913. if (pPixelFormat->dwRGBAlphaBitMask != 0)
  914. {
  915. DBG_D3D((4," Texture is 8:8:8:8"));
  916. }
  917. else
  918. {
  919. DBG_D3D((4," Texture is 8:8:8"));
  920. }
  921. }
  922. else if (pPixelFormat->dwRBitMask == 0x7c00)
  923. {
  924. if (pPixelFormat->dwRGBAlphaBitMask != 0)
  925. {
  926. DBG_D3D((4," Texture is 1:5:5:5"));
  927. }
  928. else
  929. {
  930. DBG_D3D((4," Texture is 5:5:5"));
  931. }
  932. }
  933. else if (pPixelFormat->dwRBitMask == 0xf800)
  934. {
  935. DBG_D3D((4," Texture is 5:6:5"));
  936. }
  937. else if (pPixelFormat->dwRBitMask == 0xe0)
  938. {
  939. DBG_D3D((4," Texture is 3:3:2"));
  940. }
  941. } // DumpTexture
  942. #endif