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.

746 lines
24 KiB

  1. /*
  2. ** Copyright 1991,1992, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. */
  18. #include "precomp.h"
  19. #pragma hdrstop
  20. #include <namesint.h>
  21. #include <glmath.h>
  22. #include <devlock.h>
  23. /************************************************************************/
  24. /*
  25. ** Texture Object routines.
  26. */
  27. /************************************************************************/
  28. #define __GL_CHECK_VALID_N_PARAM(failStatement) \
  29. if (n < 0) { \
  30. __glSetError(GL_INVALID_VALUE); \
  31. } \
  32. if (n == 0) { \
  33. failStatement; \
  34. } \
  35. GLvoid APIPRIVATE __glim_GenTextures(GLsizei n, GLuint* textures)
  36. {
  37. __GL_SETUP_NOT_IN_BEGIN();
  38. __GL_CHECK_VALID_N_PARAM(return);
  39. if (NULL == textures) return;
  40. ASSERTOPENGL(NULL != gc->texture.shared->namesArray,
  41. "No texture names array\n");
  42. __glNamesGenNames(gc, gc->texture.shared->namesArray, n, textures);
  43. }
  44. GLvoid APIPRIVATE __glim_DeleteTextures(GLsizei n, const GLuint* textures)
  45. {
  46. GLuint start, rangeVal, numTextures, targetIndex, i;
  47. __GLnamesArray *array;
  48. __GLtextureObject *texobj, **pBoundTexture;
  49. __GL_SETUP_NOT_IN_BEGIN();
  50. __GL_CHECK_VALID_N_PARAM(return);
  51. array = gc->texture.shared->namesArray;
  52. numTextures = gc->constants.numberOfTextures;
  53. /*
  54. ** Send the texture names in ranges to the names module to be
  55. ** deleted. Ignore any references to default textures.
  56. ** If a texture that is being deleted is currently bound,
  57. ** bind the default texture to its target.
  58. ** The names routine ignores any names that don't refer to
  59. ** textures.
  60. */
  61. start = rangeVal = textures[0];
  62. for (i=0; i < (GLuint)n; i++, rangeVal++) {
  63. if (0 == textures[i]) { /* skip default textures */
  64. /* delete up to this one */
  65. __glNamesDeleteRange(gc,array,start,rangeVal-start);
  66. /* skip over this one by setting start to the next one */
  67. start = textures[i+1];
  68. rangeVal = start-1; /* because it gets incremented later */
  69. continue;
  70. }
  71. /*
  72. ** If the texture is currently bound, bind the defaultTexture
  73. ** to its target. The problem here is identifying the target.
  74. ** One way is to look up the texobj with the name. Another is
  75. ** to look through all of the currently bound textures and
  76. ** check each for the name. It has been implemented with the
  77. ** assumption that looking through the currently bound textures
  78. ** is faster than retrieving the texobj that corresponds to
  79. ** the name.
  80. */
  81. for (targetIndex=0, pBoundTexture = gc->texture.boundTextures;
  82. targetIndex < numTextures; targetIndex++, pBoundTexture++) {
  83. /* Is the texture currently bound? */
  84. if (*pBoundTexture != &gc->texture.ddtex.texobj &&
  85. (*pBoundTexture)->texture.map.texobjs.name == textures[i]) {
  86. __GLperTextureState *pts;
  87. pts = &gc->state.texture.texture[targetIndex];
  88. /* if we don't unlock it, it won't get deleted */
  89. __glNamesUnlockData(gc, *pBoundTexture, __glCleanupTexObj);
  90. /* bind the default texture to this target */
  91. texobj = gc->texture.defaultTextures + targetIndex;
  92. ASSERTOPENGL(texobj->texture.map.texobjs.name == 0,
  93. "Non-default texture\n");
  94. gc->texture.texture[targetIndex] = &(texobj->texture);
  95. *pBoundTexture = texobj;
  96. pts->texobjs = texobj->texture.map.texobjs;
  97. pts->params = texobj->texture.map.params;
  98. /* Need to reset the current texture and such. */
  99. __GL_DELAY_VALIDATE(gc);
  100. break;
  101. }
  102. }
  103. if (textures[i] != rangeVal) {
  104. /* delete up to this one */
  105. __glNamesDeleteRange(gc,array,start,rangeVal-start);
  106. start = rangeVal = textures[i];
  107. }
  108. }
  109. __glNamesDeleteRange(gc,array,start,rangeVal-start);
  110. }
  111. // These macros used for comparing properties of 2 textures
  112. #define _DIFFERENT_TEX_PARAMS( tex1, tex2 ) \
  113. ( ! RtlEqualMemory( &(tex1)->params, &(tex2)->params, sizeof(__GLtextureParamState)) )
  114. #define _DIFFERENT_TEXDATA_FORMATS( tex1, tex2 ) \
  115. ( (tex1)->level[0].internalFormat != (tex2)->level[0].internalFormat )
  116. /*
  117. ** This routine is used by the pick routines to actually perform
  118. ** the bind.
  119. */
  120. void FASTCALL __glBindTexture(__GLcontext *gc, GLuint targetIndex,
  121. GLuint texture, GLboolean callGen)
  122. {
  123. __GLtextureObject *texobj;
  124. ASSERTOPENGL(NULL != gc->texture.shared->namesArray,
  125. "No texture names array\n");
  126. // Check if this texture is the currently bound one
  127. if( (targetIndex != __GL_TEX_TARGET_INDEX_DDRAW &&
  128. gc->texture.boundTextures[targetIndex] != &gc->texture.ddtex.texobj &&
  129. texture == gc->texture.boundTextures[targetIndex]->
  130. texture.map.texobjs.name) ||
  131. (targetIndex == __GL_TEX_TARGET_INDEX_DDRAW &&
  132. gc->texture.boundTextures[__GL_TEX_TARGET_INDEX_2D] ==
  133. &gc->texture.ddtex.texobj))
  134. {
  135. return;
  136. }
  137. /*
  138. ** Retrieve the texture object from the namesArray structure.
  139. */
  140. if (targetIndex == __GL_TEX_TARGET_INDEX_DDRAW)
  141. {
  142. targetIndex = __GL_TEX_TARGET_INDEX_2D;
  143. texobj = &gc->texture.ddtex.texobj;
  144. }
  145. else if (texture == 0)
  146. {
  147. texobj = gc->texture.defaultTextures + targetIndex;
  148. ASSERTOPENGL(NULL != texobj, "No default texture\n");
  149. ASSERTOPENGL(texobj->texture.map.texobjs.name == 0,
  150. "Non-default texture\n");
  151. }
  152. else
  153. {
  154. texobj = (__GLtextureObject *)
  155. __glNamesLockData(gc, gc->texture.shared->namesArray, texture);
  156. }
  157. /*
  158. ** Is this the first time this name has been bound?
  159. ** If so, create a new texture object and initialize it.
  160. */
  161. if (NULL == texobj) {
  162. texobj = (__GLtextureObject *)GCALLOCZ(gc, sizeof(*texobj));
  163. if (texobj == NULL)
  164. {
  165. return;
  166. }
  167. if (!__glInitTextureObject(gc, texobj, texture, targetIndex))
  168. {
  169. GCFREE(gc, texobj);
  170. return;
  171. }
  172. __glInitTextureMachine(gc, targetIndex, &(texobj->texture), GL_TRUE);
  173. __glNamesNewData(gc, gc->texture.shared->namesArray, texture, texobj);
  174. /*
  175. ** Shortcut way to lock without doing another lookup.
  176. */
  177. __glNamesLockArray(gc, gc->texture.shared->namesArray);
  178. texobj->refcount++;
  179. __glNamesUnlockArray(gc, gc->texture.shared->namesArray);
  180. __glTexPriListAdd(gc, texobj, GL_TRUE);
  181. }
  182. else {
  183. /*
  184. ** Retrieved an existing texture object. Do some
  185. ** sanity checks.
  186. */
  187. if (texobj->targetIndex != targetIndex) {
  188. __glSetError(GL_INVALID_OPERATION);
  189. return;
  190. }
  191. ASSERTOPENGL(texture == texobj->texture.map.texobjs.name,
  192. "Texture name mismatch\n");
  193. }
  194. {
  195. __GLperTextureState *pts;
  196. __GLtexture *ptm;
  197. __GLtextureObject *boundTexture;
  198. pts = &(gc->state.texture.texture[targetIndex]);
  199. ptm = &(gc->texture.texture[targetIndex]->map);
  200. boundTexture = gc->texture.boundTextures[targetIndex];
  201. /* Copy the current stackable state into the bound texture. */
  202. ptm->params = pts->params;
  203. ptm->texobjs = pts->texobjs;
  204. // If the DDraw texture is currently bound, release its
  205. // resources
  206. if (boundTexture == &gc->texture.ddtex.texobj)
  207. {
  208. glsrvUnbindDirectDrawTexture(gc);
  209. }
  210. else if (boundTexture->texture.map.texobjs.name != 0)
  211. {
  212. /* Unlock the texture that is being unbound. */
  213. __glNamesUnlockData(gc, boundTexture, __glCleanupTexObj);
  214. }
  215. /*
  216. ** Install the new texture into the correct target and save
  217. ** its pointer so it can be unlocked easily when it is unbound.
  218. */
  219. gc->texture.texture[targetIndex] = &(texobj->texture);
  220. gc->texture.boundTextures[targetIndex] = texobj;
  221. /* Copy the new texture's stackable state into the context state. */
  222. pts->params = texobj->texture.map.params;
  223. pts->texobjs = texobj->texture.map.texobjs;
  224. if (callGen)
  225. {
  226. __glGenMakeTextureCurrent(gc, &texobj->texture.map,
  227. texobj->loadKey);
  228. }
  229. __GL_DELAY_VALIDATE_MASK( gc, __GL_DIRTY_TEXTURE );
  230. // We can avoid dirtying generic if the new texture has same
  231. // properties as the old one...
  232. if( !( gc->dirtyMask & __GL_DIRTY_GENERIC ) )
  233. {
  234. // GL_DIRTY_GENERIC has not yet been set
  235. __GLtexture *newTex = &texobj->texture.map;
  236. __GLtexture *oldTex = &boundTexture->texture.map;
  237. if( (_DIFFERENT_TEX_PARAMS( newTex, oldTex )) ||
  238. (_DIFFERENT_TEXDATA_FORMATS( newTex, oldTex )) ||
  239. (texobj->targetIndex != boundTexture->targetIndex) )
  240. {
  241. __GL_DELAY_VALIDATE( gc ); // dirty generic
  242. }
  243. }
  244. }
  245. }
  246. GLvoid APIPRIVATE __glim_BindTexture(GLenum target, GLuint texture)
  247. {
  248. GLuint targetIndex;
  249. /*
  250. ** Need to validate in case a new texture was popped into
  251. ** the state immediately prior to this call.
  252. */
  253. __GL_SETUP_NOT_IN_BEGIN_VALIDATE();
  254. switch (target) {
  255. case GL_TEXTURE_1D:
  256. targetIndex = 2;
  257. break;
  258. case GL_TEXTURE_2D:
  259. targetIndex = 3;
  260. break;
  261. default:
  262. __glSetError(GL_INVALID_ENUM);
  263. return;
  264. }
  265. __glBindTexture(gc, targetIndex, texture, GL_TRUE);
  266. }
  267. #ifdef GL_WIN_multiple_textures
  268. void APIPRIVATE __glim_BindNthTextureWIN(GLuint index, GLenum target, GLuint texture)
  269. {
  270. }
  271. #endif // GL_WIN_multiple_textures
  272. GLvoid APIPRIVATE __glim_PrioritizeTextures(GLsizei n,
  273. const GLuint* textures,
  274. const GLclampf* priorities)
  275. {
  276. int i;
  277. __GLtextureObject *texobj;
  278. GLuint targetIndex;
  279. __GLtextureObject **pBoundTexture;
  280. GLclampf priority;
  281. __GL_SETUP_NOT_IN_BEGIN();
  282. __GL_CHECK_VALID_N_PARAM(return);
  283. for (i=0; i < n; i++) {
  284. /* silently ignore default texture */
  285. if (0 == textures[i]) continue;
  286. texobj = (__GLtextureObject *)
  287. __glNamesLockData(gc, gc->texture.shared->namesArray, textures[i]);
  288. /* silently ignore non-texture */
  289. if (NULL == texobj) continue;
  290. priority = __glClampf(priorities[i], __glZero, __glOne);
  291. texobj->texture.map.texobjs.priority = priority;
  292. // If this texture is currently bound, also update the
  293. // copy of the priority in the gc's state
  294. // Keeping copies is not a good design. This
  295. // should be improved
  296. for (targetIndex = 0, pBoundTexture = gc->texture.boundTextures;
  297. targetIndex < (GLuint)gc->constants.numberOfTextures;
  298. targetIndex++, pBoundTexture++)
  299. {
  300. /* Is the texture currently bound? */
  301. if (*pBoundTexture != &gc->texture.ddtex.texobj &&
  302. (*pBoundTexture)->texture.map.texobjs.name == textures[i])
  303. {
  304. gc->state.texture.texture[targetIndex].texobjs.priority =
  305. priority;
  306. break;
  307. }
  308. }
  309. __glTexPriListChangePriority(gc, texobj, GL_FALSE);
  310. __glNamesUnlockData(gc, texobj, __glCleanupTexObj);
  311. }
  312. __glNamesLockArray(gc, gc->texture.shared->namesArray);
  313. __glTexPriListRealize(gc);
  314. __glNamesUnlockArray(gc, gc->texture.shared->namesArray);
  315. }
  316. GLboolean APIPRIVATE __glim_AreTexturesResident(GLsizei n,
  317. const GLuint* textures,
  318. GLboolean* residences)
  319. {
  320. int i;
  321. __GLtextureObject *texobj;
  322. GLboolean allResident = GL_TRUE;
  323. GLboolean currentResident;
  324. __GL_SETUP_NOT_IN_BEGIN2();
  325. __GL_CHECK_VALID_N_PARAM(return GL_FALSE);
  326. for (i=0; i < n; i++) {
  327. /* Can't query a default texture. */
  328. if (0 == textures[i]) {
  329. __glSetError(GL_INVALID_VALUE);
  330. return GL_FALSE;
  331. }
  332. texobj = (__GLtextureObject *)
  333. __glNamesLockData(gc, gc->texture.shared->namesArray, textures[i]);
  334. /*
  335. ** Ensure that all of the names have corresponding textures.
  336. */
  337. if (NULL == texobj) {
  338. __glSetError(GL_INVALID_VALUE);
  339. return GL_FALSE;
  340. }
  341. if (((__GLGENcontext *)gc)->pMcdState && texobj->loadKey) {
  342. currentResident = ((GenMcdTextureStatus((__GLGENcontext *)gc, texobj->loadKey) & MCDRV_TEXTURE_RESIDENT) != 0);
  343. } else
  344. currentResident = texobj->resident;
  345. if (!currentResident) {
  346. allResident = GL_FALSE;
  347. }
  348. residences[i] = currentResident;
  349. __glNamesUnlockData(gc, texobj, __glCleanupTexObj);
  350. }
  351. return allResident;
  352. }
  353. GLboolean APIPRIVATE __glim_IsTexture(GLuint texture)
  354. {
  355. __GLtextureObject *texobj;
  356. __GL_SETUP_NOT_IN_BEGIN2();
  357. if (0 == texture) return GL_FALSE;
  358. texobj = (__GLtextureObject *)
  359. __glNamesLockData(gc, gc->texture.shared->namesArray, texture);
  360. if (texobj != NULL)
  361. {
  362. __glNamesUnlockData(gc, texobj, __glCleanupTexObj);
  363. return GL_TRUE;
  364. }
  365. return GL_FALSE;
  366. }
  367. #ifdef NT
  368. GLboolean FASTCALL __glCanShareTextures(__GLcontext *gc, __GLcontext *shareMe)
  369. {
  370. GLboolean canShare = GL_TRUE;
  371. if (gc->texture.shared != NULL)
  372. {
  373. __glNamesLockArray(gc, gc->texture.shared->namesArray);
  374. // Make sure we're not trying to replace a shared object
  375. // The spec also says that it is illegal for the new context
  376. // to have any textures
  377. canShare = gc->texture.shared->namesArray->refcount == 1 &&
  378. gc->texture.shared->namesArray->tree == NULL;
  379. __glNamesUnlockArray(gc, gc->texture.shared->namesArray);
  380. }
  381. return canShare;
  382. }
  383. void FASTCALL __glShareTextures(__GLcontext *gc, __GLcontext *shareMe)
  384. {
  385. GLint i, numTextures;
  386. if (gc->texture.shared != NULL)
  387. {
  388. // We know that the names array doesn't have any contents
  389. // so no texture names can be selected as the current texture
  390. // or anything else. Therefore it is safe to simply free
  391. // our array
  392. __glFreeSharedTextureState(gc);
  393. }
  394. __glNamesLockArray(gc, shareMe->texture.shared->namesArray);
  395. gc->texture.shared = shareMe->texture.shared;
  396. gc->texture.shared->namesArray->refcount++;
  397. // Add the new sharer's default textures to the priority list
  398. numTextures = gc->constants.numberOfTextures;
  399. for (i = 0; i < numTextures; i++)
  400. {
  401. __glTexPriListAddToList(gc, gc->texture.defaultTextures+i);
  402. }
  403. // No realization of priority list because these contexts aren't
  404. // current
  405. DBGLEVEL3(LEVEL_INFO, "Sharing textures %p with %p, count %d\n",
  406. gc, shareMe, gc->texture.shared->namesArray->refcount);
  407. __glNamesUnlockArray(gc, shareMe->texture.shared->namesArray);
  408. }
  409. #endif
  410. /******************************Public*Routine******************************\
  411. *
  412. * glsrvBindDirectDrawTexture
  413. *
  414. * Make the DirectDraw texture data in gc->texture the current 2D texture
  415. *
  416. * History:
  417. * Wed Sep 04 11:35:59 1996 -by- Drew Bliss [drewb]
  418. * Created
  419. *
  420. \**************************************************************************/
  421. BOOL APIENTRY glsrvBindDirectDrawTexture(__GLcontext *gc,
  422. int levels,
  423. LPDIRECTDRAWSURFACE *apdds,
  424. DDSURFACEDESC *pddsd,
  425. ULONG flags)
  426. {
  427. __GLmipMapLevel *lev;
  428. __GLtexture *tex;
  429. GLint levIndex;
  430. GLint width, height;
  431. GLint wlog2, hlog2;
  432. __GLddrawTexture *pddtex;
  433. ASSERTOPENGL(levels <= gc->constants.maxMipMapLevel,
  434. "Too many levels in DDraw texture\n");
  435. // Bind the fake DDraw texture.
  436. __glBindTexture(gc, __GL_TEX_TARGET_INDEX_DDRAW, __GL_TEX_DDRAW, GL_FALSE);
  437. pddtex = &gc->texture.ddtex;
  438. tex = &pddtex->texobj.texture.map;
  439. pddtex->levels = levels;
  440. memcpy(gc->texture.ddtex.pdds, apdds, levels*sizeof(LPDIRECTDRAWSURFACE));
  441. pddtex->gdds.pdds = apdds[0];
  442. pddtex->gdds.ddsd = *pddsd;
  443. pddtex->gdds.dwBitDepth =
  444. DdPixDepthToCount(pddsd->ddpfPixelFormat.dwRGBBitCount);
  445. pddtex->flags = flags;
  446. // Fill out the DirectDraw texture data
  447. width = (GLint)pddtex->gdds.ddsd.dwWidth;
  448. wlog2 = __glIntLog2(width);
  449. height = (GLint)pddtex->gdds.ddsd.dwHeight;
  450. hlog2 = __glIntLog2(height);
  451. if (wlog2 > hlog2)
  452. {
  453. tex->p = wlog2;
  454. }
  455. else
  456. {
  457. tex->p = hlog2;
  458. }
  459. lev = tex->level;
  460. for (levIndex = 0; levIndex < gc->texture.ddtex.levels; levIndex++)
  461. {
  462. // Buffer pointer is filled in at attention time.
  463. // If we're going to pass this texture to the MCD then we
  464. // fill in the surface handles at this time so they're
  465. // given to the driver at create time.
  466. if (flags & DDTEX_VIDEO_MEMORY)
  467. {
  468. lev->buffer = (__GLtextureBuffer *)
  469. ((LPDDRAWI_DDRAWSURFACE_INT)apdds[levIndex])->
  470. lpLcl->hDDSurface;
  471. }
  472. else
  473. {
  474. lev->buffer = NULL;
  475. }
  476. lev->width = width;
  477. lev->height = height;
  478. lev->width2 = width;
  479. lev->height2 = height;
  480. lev->width2f = (__GLfloat)width;
  481. lev->height2f = (__GLfloat)height;
  482. lev->widthLog2 = wlog2;
  483. lev->heightLog2 = hlog2;
  484. lev->border = 0;
  485. lev->luminanceSize = 0;
  486. lev->intensitySize = 0;
  487. if (pddtex->gdds.ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
  488. {
  489. lev->requestedFormat = tex->paletteRequestedFormat;
  490. lev->baseFormat = tex->paletteBaseFormat;
  491. lev->internalFormat = GL_COLOR_INDEX8_EXT;
  492. __glSetPaletteLevelExtract8(tex, lev, 0);
  493. lev->redSize = 0;
  494. lev->greenSize = 0;
  495. lev->blueSize = 0;
  496. lev->alphaSize = 0;
  497. }
  498. else
  499. {
  500. if (pddtex->gdds.ddsd.ddsCaps.dwCaps & DDSCAPS_ALPHA)
  501. {
  502. lev->requestedFormat = GL_RGBA;
  503. lev->baseFormat = GL_RGBA;
  504. }
  505. else
  506. {
  507. lev->requestedFormat = GL_RGB;
  508. lev->baseFormat = GL_RGB;
  509. }
  510. lev->internalFormat = GL_BGRA_EXT;
  511. lev->extract = __glExtractTexelBGRA8;
  512. lev->redSize = 8;
  513. lev->greenSize = 8;
  514. lev->blueSize = 8;
  515. lev->alphaSize = 8;
  516. }
  517. if (width != 1)
  518. {
  519. width >>= 1;
  520. wlog2--;
  521. }
  522. if (height != 1)
  523. {
  524. height >>= 1;
  525. hlog2--;
  526. }
  527. lev++;
  528. }
  529. // If the texture is in VRAM then attempt to create an MCD handle for it.
  530. // This must be done before palette operations so that
  531. // the loadKey is set.
  532. if (flags & DDTEX_VIDEO_MEMORY)
  533. {
  534. pddtex->texobj.loadKey =
  535. __glGenLoadTexture(gc, tex, MCDTEXTURE_DIRECTDRAW_SURFACES);
  536. // Remove handles that were set earlier.
  537. lev = tex->level;
  538. for (levIndex = 0; levIndex < gc->texture.ddtex.levels; levIndex++)
  539. {
  540. lev->buffer = NULL;
  541. lev++;
  542. }
  543. }
  544. else
  545. {
  546. pddtex->texobj.loadKey = 0;
  547. }
  548. // Pick up palette for paletted surface
  549. if (pddtex->gdds.ddsd.ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8)
  550. {
  551. LPDIRECTDRAWPALETTE pddp;
  552. HRESULT hr;
  553. hr = pddtex->gdds.pdds->lpVtbl->
  554. GetPalette(pddtex->gdds.pdds, &pddp);
  555. if (hr == DD_OK && pddp != NULL)
  556. {
  557. PALETTEENTRY pe[256];
  558. if (pddp->lpVtbl->GetEntries(pddp, 0, 0, 256, pe) == DD_OK)
  559. {
  560. __glim_ColorTableEXT(GL_TEXTURE_2D, GL_RGB,
  561. 256, GL_RGBA, GL_UNSIGNED_BYTE,
  562. pe, GL_FALSE);
  563. }
  564. pddp->lpVtbl->Release(pddp);
  565. }
  566. }
  567. // If we have a loadKey, make the texture current
  568. if (pddtex->texobj.loadKey != 0)
  569. {
  570. __glGenMakeTextureCurrent(gc, tex, pddtex->texobj.loadKey);
  571. }
  572. __GL_DELAY_VALIDATE(gc);
  573. return TRUE;
  574. }
  575. /******************************Public*Routine******************************\
  576. *
  577. * glsrvUnbindDirectDrawTexture
  578. *
  579. * Cleans up DirectDraw texture data
  580. *
  581. * History:
  582. * Wed Sep 04 13:45:08 1996 -by- Drew Bliss [drewb]
  583. * Created
  584. *
  585. \**************************************************************************/
  586. void APIENTRY glsrvUnbindDirectDrawTexture(__GLcontext *gc)
  587. {
  588. GLint i;
  589. __GLddrawTexture *pddtex;
  590. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  591. pddtex = &gc->texture.ddtex;
  592. // Make sure a texture is bound
  593. if (pddtex->levels <= 0)
  594. {
  595. return;
  596. }
  597. // Delete any MCD information
  598. if (pddtex->texobj.loadKey != 0)
  599. {
  600. __glGenFreeTexture(gc, &pddtex->texobj.texture.map,
  601. pddtex->texobj.loadKey);
  602. pddtex->texobj.loadKey = 0;
  603. }
  604. for (i = 0; i < pddtex->levels; i++)
  605. {
  606. // If we're currently in an attention then we locked the texture
  607. // surfaces and need to unlock them before we release them.
  608. //
  609. // Since there's no way to bind new DD textures in a batch, we
  610. // are guaranteed to have had the texture active at the beginning
  611. // of the batch and therefore we're guaranteed to have the texture
  612. // locks.
  613. if (gengc->fsLocks & LOCKFLAG_DD_TEXTURE)
  614. {
  615. DDSUNLOCK(pddtex->pdds[i],
  616. pddtex->texobj.texture.map.level[i].buffer);
  617. #if DBG
  618. pddtex->texobj.texture.map.level[i].buffer = NULL;
  619. #endif
  620. }
  621. pddtex->pdds[i]->lpVtbl->
  622. Release(pddtex->pdds[i]);
  623. #if DBG
  624. pddtex->pdds[i] = NULL;
  625. #endif
  626. }
  627. #if DBG
  628. memset(&pddtex->gdds, 0, sizeof(pddtex->gdds));
  629. #endif
  630. pddtex->levels = 0;
  631. if (gengc->fsGenLocks & LOCKFLAG_DD_TEXTURE)
  632. {
  633. gengc->fsGenLocks &= ~LOCKFLAG_DD_TEXTURE;
  634. gengc->fsLocks &= ~LOCKFLAG_DD_TEXTURE;
  635. }
  636. __GL_DELAY_VALIDATE(gc);
  637. }