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.

1337 lines
54 KiB

  1. /******************************Module*Header*******************************\
  2. *
  3. * Module Name: texparm.c
  4. * Author: Goran Devic, Mark Einkauf
  5. * Purpose: Texture memory management and parameterization for perspective textures
  6. *
  7. * Copyright (c) 1997 Cirrus Logic, Inc.
  8. *
  9. \**************************************************************************/
  10. /******************************************************************************
  11. * Include Files
  12. ******************************************************************************/
  13. #include "precomp.h"
  14. #include <excpt.h>
  15. #include <stdlib.h> /* Include standard library */
  16. #include <stdio.h> /* Include standard input/output */
  17. #include <math.h> /* Include math module */
  18. #include "mcdhw.h"
  19. #include "mcdutil.h"
  20. #include "mcdmath.h"
  21. #if 1 // 1 here to avoid tons of prints for each texture load
  22. #define MCDBG_PRINT_TEX
  23. #else
  24. #define MCDBG_PRINT_TEX MCDBG_PRINT
  25. #endif
  26. #define DEBUG_CONDITION DEBUG_TEX
  27. #include "debug.h" /* Include debug support */
  28. /******************************************************************************
  29. * Local Variables and Defines
  30. ******************************************************************************/
  31. #define F_NEG(var) (*(unsigned *)&var ^= 0x80000000)
  32. // convert from float to 16.16 long
  33. #define fix_ieee( val ) FTOL((val) * (float)65536.0)
  34. // convert from float to 8.24 long
  35. #define fix824_ieee( val ) FTOL((val) * (float)16777216.0)
  36. typedef struct {
  37. float a1, a2;
  38. float b1, b2;
  39. } QUADRATIC;
  40. typedef float * (WINAPI *CONVERT_TEXEL_FUNC)();
  41. __inline float *luminance_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  42. {
  43. // Single float used as R,G,B
  44. texel_rgba->rgbRed =
  45. texel_rgba->rgbGreen=
  46. // texel_rgba->rgbBlue = (UCHAR)(*pSrc++ * ((1<<level->luminanceSize) - 1));
  47. texel_rgba->rgbBlue = (UCHAR)(*pSrc++ * (float)255.0);
  48. return(pSrc);
  49. }
  50. // same as above, except texel = 1-color instead of color
  51. __inline float *n_luminance_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  52. {
  53. // Single float used as R,G,B
  54. texel_rgba->rgbRed =
  55. texel_rgba->rgbGreen=
  56. // texel_rgba->rgbBlue = (UCHAR)(((float)1.0 - *pSrc++) * ((1<<level->luminanceSize) - 1));
  57. texel_rgba->rgbBlue = (UCHAR)(((float)1.0 - *pSrc++) * (float)255.0);
  58. return(pSrc);
  59. }
  60. __inline float *luminance_alpha_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  61. {
  62. // MCD_NOTE: For case of LUMINANCE_ALPHA, final alpha supposed to be Atexture*Afragment - 5465
  63. // MCD_NOTE: can't do this, so we'll punt if blend on and LUMINANCE_ALPHA texture
  64. // MCD_NOTE: This code left for completeness in case hardware support added
  65. // 1st float used as R,G,B
  66. texel_rgba->rgbRed =
  67. texel_rgba->rgbGreen=
  68. // texel_rgba->rgbBlue = (UCHAR)(*pSrc++ * ((1<<level->luminanceSize) - 1));
  69. texel_rgba->rgbBlue = (UCHAR)(*pSrc++ * (float)255.0);
  70. // 2nd float is alpha
  71. // texel_rgba->rgbReserved = (UCHAR)(*pSrc++ * ((1<<level->alphaSize) - 1));
  72. texel_rgba->rgbReserved = (UCHAR)(*pSrc++ * (float)255.0);
  73. return(pSrc);
  74. }
  75. // same as above, except texel = 1-color instead of color
  76. __inline float *n_luminance_alpha_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  77. {
  78. // MCD_NOTE: For case of LUMINANCE_ALPHA, final alpha supposed to be Atexture*Afragment - 5465
  79. // MCD_NOTE: can't do this, so we'll punt if blend on and LUMINANCE_ALPHA texture
  80. // MCD_NOTE: This code left for completeness in case hardware support added
  81. // 1st float used as R,G,B
  82. texel_rgba->rgbRed =
  83. texel_rgba->rgbGreen=
  84. // texel_rgba->rgbBlue = (UCHAR)(((float)1.0 - *pSrc++) * ((1<<level->luminanceSize) - 1));
  85. texel_rgba->rgbBlue = (UCHAR)(((float)1.0 - *pSrc++) * (float)255.0);
  86. // 2nd float is alpha
  87. // texel_rgba->rgbReserved = (UCHAR)(((float)1.0 - *pSrc++) * ((1<<level->alphaSize) - 1));
  88. texel_rgba->rgbReserved = (UCHAR)(((float)1.0 - *pSrc++) * (float)255.0);
  89. return(pSrc);
  90. }
  91. __inline float *luminance_blend_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  92. {
  93. // RGB is from Texture Environment and is set by caller -
  94. // A is Luminance value in texture
  95. texel_rgba->rgbReserved = (UCHAR)(*pSrc++ * ((1<<level->luminanceSize) - 1));
  96. return(pSrc);
  97. }
  98. __inline float *luminance_alpha_blend_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  99. {
  100. // RGB is from Texture Environment and is set by caller - so ignore texel value
  101. pSrc++;
  102. // A is Luminance value in texture
  103. texel_rgba->rgbReserved = (UCHAR)(*pSrc++ * ((1<<level->luminanceSize) - 1));
  104. return(pSrc);
  105. }
  106. __inline float *alpha_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  107. {
  108. // RGB set by caller
  109. // Single float used as Alpha
  110. texel_rgba->rgbReserved = (UCHAR)(*pSrc++ * ((1<<level->alphaSize) - 1));
  111. return(pSrc);
  112. }
  113. __inline float *rgb_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  114. {
  115. // 1st float used is R
  116. texel_rgba->rgbRed = (UCHAR)(*pSrc++ * ((1<<level->redSize) - 1));
  117. // 2nd float used is G
  118. texel_rgba->rgbGreen= (UCHAR)(*pSrc++ * ((1<<level->greenSize)- 1));
  119. // 3rd float used is B
  120. texel_rgba->rgbBlue = (UCHAR)(*pSrc++ * ((1<<level->blueSize) - 1));
  121. return(pSrc);
  122. }
  123. __inline float *rgba_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  124. {
  125. // 1st float used is R
  126. texel_rgba->rgbRed = (UCHAR)(*pSrc++ * ((1<<level->redSize) - 1));
  127. // 2nd float used is G
  128. texel_rgba->rgbGreen= (UCHAR)(*pSrc++ * ((1<<level->greenSize)- 1));
  129. // 3rd float used is B
  130. texel_rgba->rgbBlue = (UCHAR)(*pSrc++ * ((1<<level->blueSize) - 1));
  131. // 4th float is alpha
  132. texel_rgba->rgbReserved = (UCHAR)(*pSrc++ * ((1<<level->alphaSize) - 1));
  133. return(pSrc);
  134. }
  135. __inline float *intensity_texel(float *pSrc, MCDMIPMAPLEVEL *level, RGBQUAD *texel_rgba )
  136. {
  137. // Single float used as R,G,B,A
  138. texel_rgba->rgbReserved =
  139. texel_rgba->rgbRed =
  140. texel_rgba->rgbGreen =
  141. texel_rgba->rgbBlue = (UCHAR)(*pSrc++ * ((1<<level->intensitySize) - 1));
  142. return(pSrc);
  143. }
  144. ULONG __MCDLoadTexture(PDEV *ppdev, DEVRC *pRc)
  145. {
  146. LL_Texture *pTexCtlBlk = pRc->pLastTexture;
  147. POFMHDL pohTextureMap = NULL;
  148. MCDTEXTURE *pTex = pTexCtlBlk->pTex;
  149. MCDMIPMAPLEVEL *level;
  150. SIZEL mapsize;
  151. UCHAR *pDest;
  152. int rowlength,row,col;
  153. ULONG alignflag;
  154. int rshift, gshift, bshift, ashift, rpos, gpos, bpos, apos;
  155. VERIFY_TEXTUREDATA_ACCESSIBLE(pTex);
  156. VERIFY_TEXTURELEVEL_ACCESSIBLE(pTex);
  157. level = pTex->pMCDTextureData->level;
  158. mapsize.cx = (int)pTexCtlBlk->fWidth;
  159. mapsize.cy = (int)pTexCtlBlk->fHeight;
  160. // FUTURE: MUST ADD EngProbeForRead, EngSecureMem/EngUnsecureMem for MIPMAPLEVEL access
  161. MCDFREE_PRINT(" __MCDLoadTexture, size = %x by %x, mask=%x, neg=%x",
  162. mapsize.cx, mapsize.cy, pTexCtlBlk->bMasking, pTexCtlBlk->bNegativeMap);
  163. if ((level[0].internalFormat == GL_BGR_EXT) ||
  164. (level[0].internalFormat == GL_BGRA_EXT))
  165. {
  166. if (pRc->MCDTexEnvState.texEnvMode==GL_BLEND)
  167. {
  168. MCDBG_PRINT_TEX(" TexEnvMode=GL_BLEND, w/ RGB/RGBA texture - load fails");
  169. return FALSE;
  170. }
  171. // FUTURE: large 32 bit textures have trouble fitting in 4M board since 512 X 32bitpp
  172. // FUTURE: requires pitch of 2048. 2048 pitch only happens at hi-res, such as
  173. // FUTURE: 1024x786 at 16bpp. However, catch-22, since at hi-res, no room for
  174. // FUTURE: backbuf+zbuf+large texture (may work on 8Meg board???)
  175. // FUTURE: THEREFORE, will reformat 32bit texture to match screen format
  176. //#define SUPPORT_32BIT_TEXTURES_ASIS --WARNING-> this path doesn't work for alphatest(mask) -
  177. //should add if() to uses "non-ASIS" path if masking
  178. #ifdef SUPPORT_32BIT_TEXTURES_ASIS
  179. // if GL_BGR_EXT or GL_BGRA_EXT internalFormat, use 8888 texel mode and copy as is in
  180. // 32bit quantities (x86 byte reversal converts BGRA to ARGB, which is what L3d needs)
  181. UCHAR *pSrc;
  182. #if DRIVER_5465
  183. pTexCtlBlk->bType = LL_TEX_8888;
  184. #else
  185. pTexCtlBlk->bType = LL_TEX_1888;
  186. #endif
  187. alignflag = MCD_TEXTURE32_ALLOCATE;
  188. pohTextureMap = ppdev->pAllocOffScnMem(ppdev, &mapsize, alignflag, NULL);
  189. // if alloc failed - try to recover
  190. if (!pohTextureMap)
  191. {
  192. pohTextureMap = __MCDForceTexture(ppdev, &mapsize, alignflag, pTexCtlBlk->fLastDrvDraw);
  193. }
  194. pTexCtlBlk->pohTextureMap = pohTextureMap;
  195. if (!pohTextureMap)
  196. {
  197. MCDBG_PRINT_TEX(" Load texture failed ");
  198. pTexCtlBlk->wXloc = 0; // set to 0 - have seen keys from deleted textures used in error
  199. pTexCtlBlk->wYloc = 0; // - have sent question about this to Microsoft (3/29/97)
  200. return FALSE;
  201. }
  202. else
  203. {
  204. // alloc of off screen memory worked - key is ptr to control block
  205. pTexCtlBlk->wXloc = (WORD)pohTextureMap->aligned_x;
  206. pTexCtlBlk->wYloc = (WORD)pohTextureMap->aligned_y;
  207. }
  208. // if we make it this far, texture allocation was successful,
  209. // copy texture to video memory
  210. pDest = ppdev->pjScreen +
  211. (pohTextureMap->aligned_y * ppdev->lDeltaScreen) +
  212. pohTextureMap->aligned_x;
  213. pSrc = level[0].pTexels;
  214. rowlength = level[0].widthImage << 2; // num bytes per row of map
  215. // texture is 4 bytes per texel
  216. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*rowlength,ENGPROBE_ALIGN_DWORD);
  217. // MCD_PERF - CONVERT memcpy of texture TO A BLIT
  218. for (row=0; row<level[0].heightImage; row++)
  219. {
  220. memcpy (pDest,pSrc,rowlength);
  221. pDest += ppdev->lDeltaScreen;
  222. pSrc += rowlength;
  223. }
  224. #else // ifdef SUPPORT_32BIT_TEXTURES_ASIS
  225. // alloc block with same color format as screen
  226. switch (ppdev->iBitmapFormat)
  227. {
  228. case BMF_8BPP:
  229. if ( pTexCtlBlk->bAlphaInTexture )
  230. // need alpha in texture
  231. alignflag = MCD_TEXTURE16_ALLOCATE;
  232. else
  233. alignflag = MCD_TEXTURE8_ALLOCATE;
  234. break;
  235. case BMF_16BPP:
  236. alignflag = MCD_TEXTURE16_ALLOCATE;
  237. break;
  238. case BMF_24BPP:
  239. case BMF_32BPP:
  240. alignflag = MCD_TEXTURE32_ALLOCATE;
  241. break;
  242. }
  243. pohTextureMap = ppdev->pAllocOffScnMem(ppdev, &mapsize, alignflag, NULL);
  244. // if alloc failed - try to recover
  245. if (!pohTextureMap)
  246. {
  247. pohTextureMap = __MCDForceTexture(ppdev, &mapsize, alignflag, pTexCtlBlk->fLastDrvDraw);
  248. }
  249. pTexCtlBlk->pohTextureMap = pohTextureMap;
  250. if (!pohTextureMap)
  251. {
  252. MCDBG_PRINT_TEX(" Load texture failed ");
  253. pTexCtlBlk->wXloc = 0; // set to 0 - have seen keys from deleted textures used in error
  254. pTexCtlBlk->wYloc = 0; // - have sent question about this to Microsoft
  255. return FALSE;
  256. }
  257. else
  258. {
  259. // alloc of off screen memory worked
  260. pTexCtlBlk->wXloc = (WORD)pohTextureMap->aligned_x;
  261. pTexCtlBlk->wYloc = (WORD)pohTextureMap->aligned_y;
  262. }
  263. // if we make it this far, texture allocation was successful,
  264. // copy texture to video memory
  265. pDest = ppdev->pjScreen +
  266. (pohTextureMap->aligned_y * ppdev->lDeltaScreen) +
  267. pohTextureMap->aligned_x;
  268. {
  269. RGBQUAD *pSrc = (RGBQUAD *)level[0].pTexels;
  270. // texture is 4 bytes per texel
  271. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage*4,ENGPROBE_ALIGN_DWORD);
  272. switch (alignflag)
  273. {
  274. case MCD_TEXTURE8_ALLOCATE:
  275. pTexCtlBlk->bType = LL_TEX_332;
  276. for (row=0; row<level[0].heightImage; row++)
  277. {
  278. for (col=0; col<level[0].widthImage; col++)
  279. {
  280. // convert from 888 to 332
  281. *(pDest + col) =
  282. ((pSrc->rgbRed >> 5) << 5) |
  283. ((pSrc->rgbGreen >> 5) << 2) |
  284. (pSrc->rgbBlue >> 6);
  285. pSrc++;
  286. }
  287. pDest += ppdev->lDeltaScreen;
  288. }
  289. break;
  290. case MCD_TEXTURE16_ALLOCATE:
  291. if ( pTexCtlBlk->bAlphaInTexture )
  292. {
  293. if (pTexCtlBlk->bMasking)
  294. {
  295. pTexCtlBlk->bType = LL_TEX_1555;
  296. ashift = 7; apos = 15; // 1 bits alp, at bits 15->12
  297. rshift = 3; rpos = 10; // 5 bits red, at bits 11->8
  298. gshift = 3; gpos = 5; // 5 bits grn, at bits 7->4
  299. bshift = 3; // 5 bits blu, at bits 3->0
  300. }
  301. else
  302. {
  303. #if DRIVER_5465
  304. pTexCtlBlk->bType = LL_TEX_4444;
  305. ashift = 4; apos = 12; // 4 bits alp, at bits 15->12
  306. rshift = 4; rpos = 8; // 4 bits red, at bits 11->8
  307. gshift = 4; gpos = 4; // 4 bits grn, at bits 7->4
  308. bshift = 4; // 4 bits blu, at bits 3->0
  309. #else // DRIVER_5465
  310. // 5464 has no 4444 support
  311. pTexCtlBlk->bType = LL_TEX_1555;
  312. ashift = 7; apos = 15; // 1 bits alp, at bits 15->12
  313. rshift = 3; rpos = 10; // 5 bits red, at bits 11->8
  314. gshift = 3; gpos = 5; // 5 bits grn, at bits 7->4
  315. bshift = 3; // 5 bits blu, at bits 3->0
  316. #endif // DRIVER_5465
  317. }
  318. }
  319. else
  320. {
  321. pTexCtlBlk->bType = LL_TEX_565;
  322. ashift = 8; apos = 16; // removes alpha altogether
  323. rshift = 3; rpos = 11; // 5 bits red, at bits 15->11
  324. gshift = 2; gpos = 5; // 6 bits grn, at bits 10->5
  325. bshift = 3; // 5 bits blu, at bits 4->0
  326. }
  327. for (row=0; row<level[0].heightImage; row++)
  328. {
  329. if (!pTexCtlBlk->bMasking)
  330. {
  331. for (col=0; col<level[0].widthImage; col++)
  332. {
  333. // convert from 8888 to 4444 or 565
  334. *(USHORT *)(pDest + (col*2)) =
  335. ((pSrc->rgbReserved >> ashift) << apos) |
  336. ((pSrc->rgbRed >> rshift) << rpos) |
  337. ((pSrc->rgbGreen >> gshift) << gpos) |
  338. (pSrc->rgbBlue >> bshift);
  339. pSrc++;
  340. }
  341. }
  342. else
  343. {
  344. for (col=0; col<level[0].widthImage; col++)
  345. {
  346. // convert from 8888 to 1555
  347. *(USHORT *)(pDest + (col*2)) =
  348. ((pSrc->rgbRed >> rshift) << rpos) |
  349. ((pSrc->rgbGreen >> gshift) << gpos) |
  350. (pSrc->rgbBlue >> bshift);
  351. // turn on mask bit (bit 15) if alpha > ref
  352. if (pSrc->rgbReserved > pRc->bAlphaTestRef)
  353. *(USHORT *)(pDest + (col*2)) |= 0x8000;
  354. pSrc++;
  355. }
  356. }
  357. pDest += ppdev->lDeltaScreen;
  358. }
  359. break;
  360. case MCD_TEXTURE32_ALLOCATE:
  361. #if DRIVER_5465
  362. if (!pTexCtlBlk->bMasking)
  363. pTexCtlBlk->bType = LL_TEX_8888;
  364. else
  365. pTexCtlBlk->bType = LL_TEX_1888;
  366. #else // DRIVER_5465
  367. pTexCtlBlk->bType = LL_TEX_1888;
  368. #endif // DRIVER_5465
  369. rowlength = level[0].widthImage << 2; // num bytes per row of map
  370. if (!pTexCtlBlk->bMasking)
  371. {
  372. for (row=0; row<level[0].heightImage; row++)
  373. {
  374. // copy the RGBQUAD as is, a whole row at a time
  375. memcpy (pDest,pSrc,rowlength);
  376. pDest += ppdev->lDeltaScreen;
  377. pSrc += level[0].widthImage; // remember pSrc is RGBQUAD*, not UCHAR*
  378. }
  379. }
  380. else
  381. {
  382. // masking on - set bit31 of texel according to alpha test
  383. for (row=0; row<level[0].heightImage; row++)
  384. {
  385. // copy the RGBQUAD as is, a whole row at a time
  386. memcpy (pDest,pSrc,rowlength);
  387. for (col=0; col<level[0].widthImage; col++)
  388. {
  389. // revisit the row, turning on mask bit (bit 31) if alpha > ref
  390. if ((pSrc+col)->rgbReserved > pRc->bAlphaTestRef)
  391. *(ULONG *)(pDest + (col*4)) |= 0x80000000;
  392. }
  393. pDest += ppdev->lDeltaScreen;
  394. pSrc += level[0].widthImage; // remember pSrc is RGBQUAD*, not UCHAR*
  395. }
  396. }
  397. break;
  398. } // endswitch
  399. } // endblock
  400. #endif // ifdef SUPPORT_32BIT_TEXTURES_ASIS
  401. }
  402. else
  403. {
  404. // if internalFormat not GL_BGR_EXT or GL_BGRA_EXT , we'll convert to screen's format
  405. // (see note below on FUTURE plans to use indexed textures without conversion)
  406. if ( (pRc->MCDTexEnvState.texEnvMode==GL_BLEND) &&
  407. (level[0].internalFormat != GL_LUMINANCE) &&
  408. (level[0].internalFormat != GL_LUMINANCE_ALPHA) &&
  409. (level[0].internalFormat != GL_INTENSITY) )
  410. {
  411. MCDBG_PRINT_TEX(" TexEnvMode=GL_BLEND, w/ non LUM or INTENSITY texture - load fails");
  412. return FALSE;
  413. }
  414. if (pRc->MCDTexEnvState.texEnvMode==GL_BLEND)
  415. {
  416. // alpha only in texture - recall we've punted if not luminance or intensity
  417. alignflag = MCD_TEXTURE8_ALLOCATE;
  418. }
  419. else
  420. {
  421. // alloc block with same color format as screen
  422. switch (ppdev->iBitmapFormat)
  423. {
  424. case BMF_8BPP:
  425. if ( pTexCtlBlk->bAlphaInTexture )
  426. // need alpha in texture
  427. alignflag = MCD_TEXTURE16_ALLOCATE;
  428. else
  429. alignflag = MCD_TEXTURE8_ALLOCATE;
  430. break;
  431. case BMF_16BPP:
  432. alignflag = MCD_TEXTURE16_ALLOCATE;
  433. break;
  434. case BMF_24BPP:
  435. case BMF_32BPP:
  436. alignflag = MCD_TEXTURE32_ALLOCATE;
  437. break;
  438. }
  439. }
  440. pohTextureMap = ppdev->pAllocOffScnMem(ppdev, &mapsize, alignflag, NULL);
  441. // if alloc failed - try to recover
  442. if (!pohTextureMap)
  443. {
  444. pohTextureMap = __MCDForceTexture(ppdev, &mapsize, alignflag, pTexCtlBlk->fLastDrvDraw);
  445. }
  446. pTexCtlBlk->pohTextureMap = pohTextureMap;
  447. if (!pohTextureMap)
  448. {
  449. MCDBG_PRINT_TEX(" Load texture failed ");
  450. // alloc of off screen memory failed
  451. pTexCtlBlk->wXloc = 0; // set to 0 - have seen keys from deleted textures uses in error
  452. pTexCtlBlk->wYloc = 0; // - have sent question about this to Microsoft
  453. return FALSE;
  454. }
  455. else
  456. {
  457. // alloc of off screen memory worked - key is ptr to control block
  458. pTexCtlBlk->wXloc = (WORD)pohTextureMap->aligned_x;
  459. pTexCtlBlk->wYloc = (WORD)pohTextureMap->aligned_y;
  460. }
  461. // if we make it this far, texture allocation was successful,
  462. // copy texture to video memory
  463. pDest = ppdev->pjScreen +
  464. (pohTextureMap->aligned_y * ppdev->lDeltaScreen) +
  465. pohTextureMap->aligned_x;
  466. // MCD_NOTE concerning indexed textures...
  467. // MCD_NOTE - will convert indexed textures to same format as screen and
  468. // MCD_NOTE - store as RGB texture, until hw palette use coded and debugged.
  469. // FUTURE: use texture palettes in HW - possible complications are:
  470. // FUTURE: -palette size not fixed - data format can be 16 bit index
  471. // FUTURE: -palette can only be used when screen not in 8 bit mode
  472. // FUTURE: -5465 bug where cursor interaction can corrupt palette
  473. // FUTURE: -MISC_TEST bit set needed for some reason (see CGL code/ask Dan)
  474. switch (level[0].internalFormat)
  475. {
  476. case GL_COLOR_INDEX8_EXT:
  477. {
  478. // indices are 8 bit
  479. UCHAR *pSrc = level[0].pTexels;
  480. RGBQUAD *pPaletteData;
  481. VERIFY_TEXTUREPALETTE8_ACCESSIBLE(pTex);
  482. pPaletteData = pTex->pMCDTextureData->paletteData;
  483. // texture is 1 BYTE per texel
  484. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage,ENGPROBE_ALIGN_BYTE);
  485. switch (alignflag)
  486. {
  487. case MCD_TEXTURE8_ALLOCATE:
  488. pTexCtlBlk->bType = LL_TEX_332;
  489. for (row=0; row<level[0].heightImage; row++)
  490. {
  491. for (col=0; col<level[0].widthImage; col++)
  492. {
  493. // convert from 888 to 332
  494. *(pDest + col) =
  495. ((pPaletteData[*pSrc].rgbRed >> 5) << 5) |
  496. ((pPaletteData[*pSrc].rgbGreen >> 5) << 2) |
  497. (pPaletteData[*pSrc].rgbBlue >> 6);
  498. pSrc++; // increment by 1 byte
  499. }
  500. pDest += ppdev->lDeltaScreen;
  501. }
  502. break;
  503. case MCD_TEXTURE16_ALLOCATE:
  504. #if DRIVER_5465
  505. pTexCtlBlk->bType = LL_TEX_4444;
  506. ashift = 4; apos = 12; // 4 bits alp, at bits 15->12
  507. rshift = 4; rpos = 8; // 4 bits red, at bits 11->8
  508. gshift = 4; gpos = 4; // 4 bits grn, at bits 7->4
  509. bshift = 4; // 4 bits blu, at bits 3->0
  510. #else // DRIVER_5465
  511. pTexCtlBlk->bType = LL_TEX_565;
  512. ashift = 8; apos = 16; // removes alpha altogether
  513. rshift = 3; rpos = 11; // 5 bits red, at bits 15->11
  514. gshift = 2; gpos = 5; // 6 bits grn, at bits 10->5
  515. bshift = 3; // 5 bits blu, at bits 4->0
  516. #endif // DRIVER_5465
  517. for (row=0; row<level[0].heightImage; row++)
  518. {
  519. for (col=0; col<level[0].widthImage; col++)
  520. {
  521. // convert from 8888 to 565
  522. *(USHORT *)(pDest + (col*2)) =
  523. ((pPaletteData[*pSrc].rgbReserved >> ashift) << apos) |
  524. ((pPaletteData[*pSrc].rgbRed >> rshift) << rpos) |
  525. ((pPaletteData[*pSrc].rgbGreen >> gshift) << gpos) |
  526. (pPaletteData[*pSrc].rgbBlue >> bshift);
  527. pSrc++; // increment by 1 byte
  528. }
  529. pDest += ppdev->lDeltaScreen;
  530. }
  531. break;
  532. case MCD_TEXTURE32_ALLOCATE:
  533. #if DRIVER_5465
  534. pTexCtlBlk->bType = LL_TEX_8888;
  535. #else
  536. pTexCtlBlk->bType = LL_TEX_1888;
  537. #endif
  538. for (row=0; row<level[0].heightImage; row++)
  539. {
  540. for (col=0; col<level[0].widthImage; col++)
  541. {
  542. // copy the RGBQUAD as is
  543. *(DWORD *)(pDest + (col*4)) = *(DWORD *)(&pPaletteData[*pSrc]);
  544. pSrc++; // increment by 1 byte
  545. }
  546. pDest += ppdev->lDeltaScreen;
  547. }
  548. break;
  549. }
  550. }
  551. break;
  552. case GL_COLOR_INDEX16_EXT:
  553. // indices are 16 bit
  554. {
  555. USHORT *pSrc = (USHORT *)level[0].pTexels;
  556. RGBQUAD *pPaletteData;
  557. VERIFY_TEXTUREPALETTE16_ACCESSIBLE(pTex);
  558. pPaletteData = pTex->pMCDTextureData->paletteData;
  559. // texture is 2 bytes per texel
  560. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage*2,ENGPROBE_ALIGN_WORD);
  561. switch (alignflag)
  562. {
  563. case MCD_TEXTURE8_ALLOCATE:
  564. pTexCtlBlk->bType = LL_TEX_332;
  565. for (row=0; row<level[0].heightImage; row++)
  566. {
  567. for (col=0; col<level[0].widthImage; col++)
  568. {
  569. // convert from 888 to 332
  570. *(pDest + col) =
  571. ((pPaletteData[*pSrc].rgbRed >> 5) << 5) |
  572. ((pPaletteData[*pSrc].rgbGreen >> 5) << 2) |
  573. (pPaletteData[*pSrc].rgbBlue >> 6);
  574. pSrc++; // increment by 1 16bit word
  575. }
  576. pDest += ppdev->lDeltaScreen;
  577. }
  578. break;
  579. case MCD_TEXTURE16_ALLOCATE:
  580. #if DRIVER_5465
  581. pTexCtlBlk->bType = LL_TEX_4444;
  582. ashift = 4; apos = 12; // 4 bits alp, at bits 15->12
  583. rshift = 4; rpos = 8; // 4 bits red, at bits 11->8
  584. gshift = 4; gpos = 4; // 4 bits grn, at bits 7->4
  585. bshift = 4; // 4 bits blu, at bits 3->0
  586. #else // DRIVER_5465
  587. pTexCtlBlk->bType = LL_TEX_565;
  588. ashift = 8; apos = 16; // removes alpha altogether
  589. rshift = 3; rpos = 11; // 5 bits red, at bits 15->11
  590. gshift = 2; gpos = 5; // 6 bits grn, at bits 10->5
  591. bshift = 3; // 5 bits blu, at bits 4->0
  592. #endif // DRIVER_5465
  593. for (row=0; row<level[0].heightImage; row++)
  594. {
  595. for (col=0; col<level[0].widthImage; col++)
  596. {
  597. // convert from 8888 to 565
  598. *(USHORT *)(pDest + (col*2)) =
  599. ((pPaletteData[*pSrc].rgbReserved >> ashift) << apos) |
  600. ((pPaletteData[*pSrc].rgbRed >> rshift) << rpos) |
  601. ((pPaletteData[*pSrc].rgbGreen >> gshift) << gpos) |
  602. (pPaletteData[*pSrc].rgbBlue >> bshift);
  603. pSrc++; // increment by 1 16bit word
  604. }
  605. pDest += ppdev->lDeltaScreen;
  606. }
  607. break;
  608. case MCD_TEXTURE32_ALLOCATE:
  609. #if DRIVER_5465
  610. pTexCtlBlk->bType = LL_TEX_8888;
  611. #else
  612. pTexCtlBlk->bType = LL_TEX_1888;
  613. #endif
  614. for (row=0; row<level[0].heightImage; row++)
  615. {
  616. for (col=0; col<level[0].widthImage; col++)
  617. {
  618. // copy the RGBQUAD as is
  619. *(DWORD *)(pDest + (col*4)) = *(DWORD *)(&pPaletteData[*pSrc]);
  620. pSrc++; // increment by 1 16bit word
  621. }
  622. pDest += ppdev->lDeltaScreen;
  623. }
  624. break;
  625. }
  626. }
  627. break;
  628. case GL_LUMINANCE:
  629. case GL_LUMINANCE_ALPHA:
  630. case GL_ALPHA:
  631. case GL_RGB:
  632. case GL_RGBA:
  633. case GL_INTENSITY:
  634. // pTexels is pointer to sequence of floats
  635. // read pTexel value, convert to RGBA using redSize, greenSize, etc.,
  636. // and store in current screen format.
  637. {
  638. float *pSrc;
  639. RGBQUAD texel_rgba;
  640. CONVERT_TEXEL_FUNC pTexelFunc;
  641. int sweetspot=0;
  642. // texture is 1, 2, 3, or 4 floats per texel, each float is 4 bytes
  643. pSrc = (float *)level[0].pTexels;
  644. texel_rgba.rgbReserved = 0xff; // initialize for cases of constant Alpha
  645. // FUTURE: We currently punt correctly if global blend enabled with texture alpha since
  646. // FUTURE: can't do blend two levels of blend - However, 5465 doesn't modulate alpha
  647. // FUTURE: of texture with alpha of fragment as req'd by GL_LUMINANCE_ALPHA
  648. // FUTURE: with Modulate or Blend, and RGBA with Modulate - therefore alpha stored
  649. // FUTURE: for these 3 cases is wrong - and if blend turned on later, results wrong
  650. switch (level[0].internalFormat)
  651. {
  652. case GL_LUMINANCE:
  653. // texture is 1 float(4 bytes) per texel
  654. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage*4,ENGPROBE_ALIGN_DWORD);
  655. if ( pRc->MCDTexEnvState.texEnvMode==GL_BLEND )
  656. {
  657. pTexelFunc = luminance_blend_texel;
  658. // texel_rgba.rgbRed = (int)(pRc->MCDTexEnvState.texEnvColor.r * pRc->rScale) >> 16;
  659. // texel_rgba.rgbGreen= (int)(pRc->MCDTexEnvState.texEnvColor.g * pRc->gScale) >> 16;
  660. // texel_rgba.rgbBlue = (int)(pRc->MCDTexEnvState.texEnvColor.b * pRc->bScale) >> 16;
  661. }
  662. else
  663. if (pTexCtlBlk->bNegativeMap)
  664. {
  665. pTexelFunc = n_luminance_texel;
  666. sweetspot++;
  667. }
  668. else
  669. {
  670. pTexelFunc = luminance_texel;
  671. }
  672. break;
  673. case GL_LUMINANCE_ALPHA:
  674. // texture is 2 floats(8 bytes) per texel
  675. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage*8,ENGPROBE_ALIGN_DWORD);
  676. if ( pRc->MCDTexEnvState.texEnvMode==GL_BLEND )
  677. {
  678. pTexelFunc = luminance_alpha_blend_texel;
  679. // texel_rgba.rgbRed = (int)(pRc->MCDTexEnvState.texEnvColor.r * pRc->rScale) >> 16;
  680. // texel_rgba.rgbGreen= (int)(pRc->MCDTexEnvState.texEnvColor.g * pRc->gScale) >> 16;
  681. // texel_rgba.rgbBlue = (int)(pRc->MCDTexEnvState.texEnvColor.b * pRc->bScale) >> 16;
  682. }
  683. else
  684. if (pTexCtlBlk->bNegativeMap)
  685. pTexelFunc = n_luminance_alpha_texel;
  686. else
  687. pTexelFunc = luminance_alpha_texel;
  688. break;
  689. case GL_ALPHA:
  690. // FUTURE: GL_BLEND texture env defined in GL1.1 for GL_ALPHA,GL_RGB,GL_RGBA
  691. // R, G, B assumed 0
  692. // texture is 1 float(4 bytes) per texel
  693. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage*4,ENGPROBE_ALIGN_DWORD);
  694. texel_rgba.rgbRed = texel_rgba.rgbGreen = texel_rgba.rgbBlue = 0;
  695. pTexelFunc = alpha_texel;
  696. break;
  697. case GL_RGB:
  698. // texture is 3 float(12 bytes) per texel
  699. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage*12,ENGPROBE_ALIGN_DWORD);
  700. pTexelFunc = rgb_texel;
  701. break;
  702. case GL_RGBA:
  703. // texture is 4 float(16 bytes) per texel
  704. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage*16,ENGPROBE_ALIGN_DWORD);
  705. pTexelFunc = rgba_texel;
  706. break;
  707. case GL_INTENSITY:
  708. // texture is 1 float(4 bytes) per texel
  709. VERIFY_TEXELS_ACCESSIBLE(pSrc,level[0].heightImage*level[0].widthImage*4,ENGPROBE_ALIGN_DWORD);
  710. pTexelFunc = intensity_texel;
  711. break;
  712. }
  713. switch (alignflag)
  714. {
  715. case MCD_TEXTURE8_ALLOCATE:
  716. if (pRc->MCDTexEnvState.texEnvMode==GL_BLEND)
  717. {
  718. // this works for GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY only
  719. pTexCtlBlk->bType = LL_TEX_8_ALPHA;
  720. for (row=0; row<level[0].heightImage; row++)
  721. {
  722. for (col=0; col<level[0].widthImage; col++)
  723. {
  724. pSrc = pTexelFunc(pSrc,&level[0],&texel_rgba);
  725. *(pDest + col) = texel_rgba.rgbReserved;
  726. }
  727. pDest += ppdev->lDeltaScreen;
  728. }
  729. }
  730. else
  731. {
  732. pTexCtlBlk->bType = LL_TEX_332;
  733. for (row=0; row<level[0].heightImage; row++)
  734. {
  735. for (col=0; col<level[0].widthImage; col++)
  736. {
  737. pSrc = pTexelFunc(pSrc,&level[0],&texel_rgba);
  738. // convert from 888 to 332
  739. *(pDest + col) =
  740. ((texel_rgba.rgbRed >> 5) << 5) |
  741. ((texel_rgba.rgbGreen >> 5) << 2) |
  742. (texel_rgba.rgbBlue >> 6);
  743. }
  744. pDest += ppdev->lDeltaScreen;
  745. }
  746. }
  747. break;
  748. case MCD_TEXTURE16_ALLOCATE:
  749. if ( pTexCtlBlk->bAlphaInTexture )
  750. {
  751. if (pTexCtlBlk->bMasking)
  752. {
  753. pTexCtlBlk->bType = LL_TEX_1555;
  754. ashift = 7; apos = 15; // 1 bits alp, at bits 15->12
  755. rshift = 3; rpos = 10; // 5 bits red, at bits 11->8
  756. gshift = 3; gpos = 5; // 5 bits grn, at bits 7->4
  757. bshift = 3; // 5 bits blu, at bits 3->0
  758. }
  759. else
  760. {
  761. #if DRIVER_5465
  762. pTexCtlBlk->bType = LL_TEX_4444;
  763. ashift = 4; apos = 12; // 4 bits alp, at bits 15->12
  764. rshift = 4; rpos = 8; // 4 bits red, at bits 11->8
  765. gshift = 4; gpos = 4; // 4 bits grn, at bits 7->4
  766. bshift = 4; // 4 bits blu, at bits 3->0
  767. #else // DRIVER_5465
  768. // 5464 has no 4444 support
  769. pTexCtlBlk->bType = LL_TEX_1555;
  770. ashift = 7; apos = 15; // 1 bits alp, at bits 15->12
  771. rshift = 3; rpos = 10; // 5 bits red, at bits 11->8
  772. gshift = 3; gpos = 5; // 5 bits grn, at bits 7->4
  773. bshift = 3; // 5 bits blu, at bits 3->0
  774. #endif // DRIVER_5465
  775. }
  776. }
  777. else
  778. {
  779. pTexCtlBlk->bType = LL_TEX_565;
  780. ashift = 8; apos = 16; // removes alpha altogether
  781. rshift = 3; rpos = 11; // 5 bits red, at bits 15->11
  782. gshift = 2; gpos = 5; // 6 bits grn, at bits 10->5
  783. bshift = 3; // 5 bits blu, at bits 4->0
  784. sweetspot++;
  785. }
  786. for (row=0; row<level[0].heightImage; row++)
  787. {
  788. if (!pTexCtlBlk->bMasking)
  789. {
  790. if (sweetspot<2)
  791. {
  792. for (col=0; col<level[0].widthImage; col++)
  793. {
  794. pSrc = pTexelFunc(pSrc,&level[0],&texel_rgba);
  795. // convert from 8888 to 4444 or 565
  796. *(USHORT *)(pDest + (col*2)) =
  797. ((texel_rgba.rgbReserved >> ashift) << apos) |
  798. ((texel_rgba.rgbRed >> rshift) << rpos) |
  799. ((texel_rgba.rgbGreen >> gshift) << gpos) |
  800. (texel_rgba.rgbBlue >> bshift);
  801. }
  802. }
  803. else
  804. {
  805. // n_luminance_texel -> 565
  806. for (col=0; col<level[0].widthImage; col++)
  807. {
  808. ULONG _8bitequiv;
  809. ULONG redblue;
  810. ULONG green;
  811. _8bitequiv = FTOL(((float)1.0 - *pSrc++) * (float)255.0);
  812. redblue = _8bitequiv >> 3; // 5 bits for r,b
  813. green = (_8bitequiv << 3) & 0x07e0; // 6 bits for g, shift to middle
  814. // convert to 565
  815. *(USHORT *)(pDest + (col*2)) = (USHORT)
  816. ((redblue<<11) | green | redblue);
  817. }
  818. }
  819. }
  820. else
  821. {
  822. for (col=0; col<level[0].widthImage; col++)
  823. {
  824. pSrc = pTexelFunc(pSrc,&level[0],&texel_rgba);
  825. // convert from 8888 to 4444 or 565
  826. *(USHORT *)(pDest + (col*2)) =
  827. ((texel_rgba.rgbReserved >> ashift) << apos) |
  828. ((texel_rgba.rgbRed >> rshift) << rpos) |
  829. ((texel_rgba.rgbGreen >> gshift) << gpos) |
  830. (texel_rgba.rgbBlue >> bshift);
  831. // turn on mask bit (bit 15) if alpha > ref
  832. if (texel_rgba.rgbReserved > pRc->bAlphaTestRef)
  833. *(USHORT *)(pDest + (col*2)) |= 0x8000;
  834. }
  835. }
  836. pDest += ppdev->lDeltaScreen;
  837. }
  838. break;
  839. case MCD_TEXTURE32_ALLOCATE:
  840. #if DRIVER_5465
  841. if (!pTexCtlBlk->bMasking)
  842. pTexCtlBlk->bType = LL_TEX_8888;
  843. else
  844. pTexCtlBlk->bType = LL_TEX_1888;
  845. #else // DRIVER_5465
  846. pTexCtlBlk->bType = LL_TEX_1888;
  847. #endif // DRIVER_5465
  848. for (row=0; row<level[0].heightImage; row++)
  849. {
  850. if (!pTexCtlBlk->bMasking)
  851. {
  852. for (col=0; col<level[0].widthImage; col++)
  853. {
  854. pSrc = pTexelFunc(pSrc,&level[0],&texel_rgba);
  855. // copy the RGBQUAD as is
  856. *(RGBQUAD *)(pDest + (col*4)) = texel_rgba;
  857. }
  858. }
  859. else
  860. {
  861. // masking on - set bit31 of texel according to alpha test
  862. for (col=0; col<level[0].widthImage; col++)
  863. {
  864. pSrc = pTexelFunc(pSrc,&level[0],&texel_rgba);
  865. // turn on mask bit (bit 8) of alpha component, if alpha > ref
  866. if (texel_rgba.rgbReserved > pRc->bAlphaTestRef)
  867. texel_rgba.rgbReserved|=0x80;
  868. // copy the RGBQUAD as is
  869. *(RGBQUAD *)(pDest + (col*4)) = texel_rgba;
  870. }
  871. }
  872. pDest += ppdev->lDeltaScreen;
  873. }
  874. break;
  875. }
  876. }
  877. break;
  878. } // endswitch
  879. }
  880. // if texture width or height less than 16, stretch it to 16x16
  881. if ((level[0].widthImage < 16) || (level[0].heightImage < 16))
  882. {
  883. int col_copies, row_copies, h, w;
  884. UCHAR *colsrc, *coldest, *rowdest;
  885. int bpt;
  886. // bytes per texel
  887. switch (alignflag)
  888. {
  889. case MCD_TEXTURE8_ALLOCATE: bpt = 1; break;
  890. case MCD_TEXTURE16_ALLOCATE: bpt = 2; break;
  891. case MCD_TEXTURE32_ALLOCATE: bpt = 4; break;
  892. }
  893. // for width stretch - 8 requires 2 copies, 4 requires 4, 2 requires 8, 1 requires 16
  894. col_copies = (16 / level[0].widthImage);
  895. // for height stretch - 8 requires 2 copies, 4 requires 4, 2 requires 8, 1 requires 16
  896. // if already at least 16 high, then width stretch all that's needed, so prevent row copy
  897. row_copies = (level[0].heightImage < 16) ? (16/level[0].heightImage) : 0;
  898. // start with last row
  899. h = level[0].heightImage - 1;
  900. while (h >= 0)
  901. {
  902. int rc; // row copy counter
  903. colsrc = coldest =
  904. ppdev->pjScreen + ((pohTextureMap->aligned_y + h) * ppdev->lDeltaScreen) +
  905. pohTextureMap->aligned_x;
  906. w = level[0].widthImage;
  907. // start at last texel of current row
  908. // will copy last texel col_copies times to 15th, 14th, etc. texel(s)
  909. colsrc += ( w - 1) * bpt;
  910. coldest += (16 - 1) * bpt;
  911. while (w--)
  912. {
  913. int cc=0;
  914. // copy original texel col_copies times
  915. while (cc<col_copies)
  916. {
  917. // copy texel of bpt size
  918. memcpy (coldest,colsrc,bpt);
  919. // src remains the same, dest is decremented
  920. coldest-=bpt;
  921. cc++;
  922. }
  923. colsrc-=bpt;
  924. }
  925. // now row is at least 16 texels
  926. // NOTE: may have been > 16 originally -
  927. // If >= 16 originally, the "cc<col_copies" loop above
  928. // would never have executed, and the "w--" loop would get
  929. // colsrc back to start of row - inefficient but typically
  930. // width=height so case of width>=16 rare
  931. // colsrc points to start of row
  932. colsrc = ppdev->pjScreen +
  933. ((pohTextureMap->aligned_y + h) * ppdev->lDeltaScreen) +
  934. pohTextureMap->aligned_x;
  935. // compute where row should be copied to for expansion heightwise
  936. rowdest = ppdev->pjScreen +
  937. ((pohTextureMap->aligned_y+(h * row_copies)) * ppdev->lDeltaScreen) +
  938. pohTextureMap->aligned_x;
  939. rc=0;
  940. // width of row is now 16, if original less than 16
  941. w = (level[0].widthImage < 16) ? 16 : level[0].widthImage;
  942. while (rc<row_copies)
  943. {
  944. // copy row
  945. memcpy (rowdest,colsrc,w*bpt);
  946. // src remains the same, dest is incremented
  947. rowdest += ppdev->lDeltaScreen;
  948. rc++;
  949. }
  950. h--;
  951. } // endwhile
  952. }
  953. return TRUE;
  954. }
  955. #if 1 // 0 here for simplest form of force
  956. POFMHDL __MCDForceTexture (PDEV *ppdev, SIZEL *mapsize, int alignflag, float time_stamp)
  957. {
  958. int attempt=4;
  959. LL_Texture *pTexCtlBlk, *pTexCandidate;
  960. POFMHDL pohTextureMap=NULL;
  961. float cand_time_stamp;
  962. MCDFORCE_PRINT(" __MCDForceTexture, pri=%d",(int)time_stamp);
  963. // wait until pending drawing completes, since offscreen memory may be moved by this routine
  964. WAIT_HW_IDLE(ppdev);
  965. while (!pohTextureMap && attempt)
  966. {
  967. switch(attempt)
  968. {
  969. case 4:
  970. // 1st try:look for texture of same (or bigger) size of current, but with lower time_stamp
  971. // MCD_NOTE2: texture cache manager assumes alignflag same for all textures
  972. // MCD_NOTE2: this may not be true if 32bpp textures ever supported as is
  973. pTexCtlBlk = ppdev->pFirstTexture->next;
  974. pTexCandidate = NULL;
  975. cand_time_stamp = time_stamp;
  976. MCDFORCE_PRINT(" Force, case 4");
  977. while (pTexCtlBlk)
  978. {
  979. MCDFORCE_PRINT(" loop: h=%x w=%x, pri=%d",
  980. (LONG)pTexCtlBlk->fHeight,(LONG)pTexCtlBlk->fWidth,(int)pTexCtlBlk->fLastDrvDraw);
  981. if ( pTexCtlBlk->pohTextureMap &&
  982. (mapsize->cy <= (LONG)pTexCtlBlk->fHeight) &&
  983. (mapsize->cx <= (LONG)pTexCtlBlk->fWidth) &&
  984. (pTexCtlBlk->fLastDrvDraw < cand_time_stamp) )
  985. {
  986. cand_time_stamp = pTexCtlBlk->fLastDrvDraw;
  987. pTexCandidate = pTexCtlBlk;
  988. }
  989. pTexCtlBlk = pTexCtlBlk->next;
  990. }
  991. // if we found a candidate, free it
  992. if (pTexCandidate)
  993. {
  994. MCDFORCE_PRINT(" freeing cand: h=%x w=%x, pri=%d",
  995. (LONG)pTexCandidate->fHeight,(LONG)pTexCandidate->fWidth,(int)pTexCandidate->fLastDrvDraw);
  996. ppdev->pFreeOffScnMem(ppdev, pTexCandidate->pohTextureMap);
  997. pTexCandidate->pohTextureMap = NULL;
  998. }
  999. break;
  1000. case 3:
  1001. // 2nd try:look for texture of same or bigger size of current, with any time_stamp
  1002. pTexCtlBlk = ppdev->pFirstTexture->next;
  1003. pTexCandidate = NULL;
  1004. MCDFORCE_PRINT(" Force, case 3");
  1005. while (pTexCtlBlk)
  1006. {
  1007. MCDFORCE_PRINT(" loop: h=%x w=%x",(LONG)pTexCtlBlk->fHeight,(LONG)pTexCtlBlk->fWidth);
  1008. if ( pTexCtlBlk->pohTextureMap &&
  1009. (mapsize->cy <= (LONG)pTexCtlBlk->fHeight) &&
  1010. (mapsize->cx <= (LONG)pTexCtlBlk->fWidth) )
  1011. {
  1012. // if already found a candidate, check if new find smaller
  1013. // if so it's new candidate, since we want to free smallest region
  1014. if (pTexCandidate)
  1015. {
  1016. if ((pTexCtlBlk->fHeight < pTexCandidate->fHeight) ||
  1017. (pTexCtlBlk->fWidth < pTexCandidate->fWidth))
  1018. {
  1019. // new find is better choice
  1020. pTexCandidate = pTexCtlBlk;
  1021. }
  1022. }
  1023. else
  1024. {
  1025. // first find - default candidate
  1026. pTexCandidate = pTexCtlBlk;
  1027. }
  1028. }
  1029. pTexCtlBlk = pTexCtlBlk->next;
  1030. }
  1031. // if we found a candidate, free it
  1032. if (pTexCandidate)
  1033. {
  1034. MCDFORCE_PRINT(" freeing cand: h=%x w=%x, pri=%d",
  1035. (LONG)pTexCandidate->fHeight,(LONG)pTexCandidate->fWidth,(int)pTexCandidate->fLastDrvDraw);
  1036. ppdev->pFreeOffScnMem(ppdev, pTexCandidate->pohTextureMap);
  1037. pTexCandidate->pohTextureMap = NULL;
  1038. }
  1039. break;
  1040. case 2:
  1041. // 3rd try:free all textures with time_stamp less than current
  1042. pTexCtlBlk = ppdev->pFirstTexture->next;
  1043. MCDFORCE_PRINT(" Force, case 2");
  1044. while (pTexCtlBlk)
  1045. {
  1046. if ( pTexCtlBlk->pohTextureMap &&
  1047. (pTexCtlBlk->fLastDrvDraw < time_stamp) )
  1048. {
  1049. ppdev->pFreeOffScnMem(ppdev, pTexCtlBlk->pohTextureMap);
  1050. pTexCtlBlk->pohTextureMap = NULL;
  1051. }
  1052. pTexCtlBlk = pTexCtlBlk->next;
  1053. }
  1054. break;
  1055. case 1:
  1056. // Last try:free all textures
  1057. pTexCtlBlk = ppdev->pFirstTexture->next;
  1058. MCDFORCE_PRINT(" Force, case 1");
  1059. while (pTexCtlBlk)
  1060. {
  1061. if (pTexCtlBlk->pohTextureMap)
  1062. {
  1063. ppdev->pFreeOffScnMem(ppdev, pTexCtlBlk->pohTextureMap);
  1064. pTexCtlBlk->pohTextureMap = NULL;
  1065. }
  1066. pTexCtlBlk = pTexCtlBlk->next;
  1067. }
  1068. break;
  1069. } // endswitch
  1070. // try it now...
  1071. pohTextureMap = ppdev->pAllocOffScnMem(ppdev, mapsize, alignflag, NULL);
  1072. attempt--;
  1073. }
  1074. MCDFORCE_PRINT(" Force RESULT= %x",pohTextureMap);
  1075. return (pohTextureMap);
  1076. }
  1077. #else // simple force
  1078. // simplest force algorithm
  1079. POFMHDL __MCDForceTexture (PDEV *ppdev, SIZEL *mapsize, int alignflag, float time_stamp)
  1080. {
  1081. int attempts;
  1082. LL_Texture *pTexCtlBlk;
  1083. POFMHDL pohTextureMap;
  1084. WAIT_HW_IDLE(ppdev); // wait until pending drawing completes, since offscreen memory may be moved by this routine
  1085. pTexCtlBlk = ppdev->pFirstTexture->next;
  1086. while (pTexCtlBlk)
  1087. {
  1088. if (pTexCtlBlk->pohTextureMap)
  1089. {
  1090. ppdev->pFreeOffScnMem(ppdev, pTexCtlBlk->pohTextureMap);
  1091. pTexCtlBlk->pohTextureMap = NULL;
  1092. }
  1093. pTexCtlBlk = pTexCtlBlk->next;
  1094. }
  1095. // try it now..
  1096. pohTextureMap = ppdev->pAllocOffScnMem(ppdev, mapsize, alignflag, NULL);
  1097. return (pohTextureMap);
  1098. }
  1099. #endif //simple force