Source code of Windows XP (NT5)
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.

1550 lines
42 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 <glmath.h>
  21. #include <devlock.h>
  22. static __GLtexture *CheckTexImageArgs(__GLcontext *gc, GLenum target, GLint lod,
  23. GLint components, GLint border,
  24. GLenum format, GLenum type, GLint dim)
  25. {
  26. __GLtexture *tex = __glLookUpTexture(gc, target);
  27. if (!tex || (tex->dim != dim)) {
  28. bad_enum:
  29. __glSetError(GL_INVALID_ENUM);
  30. return 0;
  31. }
  32. switch (type) {
  33. case GL_BITMAP:
  34. if (format != GL_COLOR_INDEX) goto bad_enum;
  35. case GL_BYTE:
  36. case GL_UNSIGNED_BYTE:
  37. case GL_SHORT:
  38. case GL_UNSIGNED_SHORT:
  39. case GL_INT:
  40. case GL_UNSIGNED_INT:
  41. case GL_FLOAT:
  42. break;
  43. default:
  44. goto bad_enum;
  45. }
  46. switch (format) {
  47. case GL_COLOR_INDEX: case GL_RED:
  48. case GL_GREEN: case GL_BLUE:
  49. case GL_ALPHA: case GL_RGB:
  50. case GL_RGBA: case GL_LUMINANCE:
  51. case GL_LUMINANCE_ALPHA:
  52. #ifdef GL_EXT_bgra
  53. case GL_BGRA_EXT:
  54. case GL_BGR_EXT:
  55. #endif
  56. break;
  57. default:
  58. goto bad_enum;
  59. }
  60. if ((lod < 0) || (lod >= gc->constants.maxMipMapLevel)) {
  61. __glSetError(GL_INVALID_VALUE);
  62. return 0;
  63. }
  64. switch (components) {
  65. case GL_LUMINANCE: case 1:
  66. case GL_LUMINANCE4: case GL_LUMINANCE8:
  67. case GL_LUMINANCE12: case GL_LUMINANCE16:
  68. break;
  69. case GL_LUMINANCE_ALPHA: case 2:
  70. case GL_LUMINANCE4_ALPHA4: case GL_LUMINANCE6_ALPHA2:
  71. case GL_LUMINANCE8_ALPHA8: case GL_LUMINANCE12_ALPHA4:
  72. case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16:
  73. break;
  74. case GL_RGB: case 3:
  75. case GL_R3_G3_B2: case GL_RGB4:
  76. case GL_RGB5: case GL_RGB8:
  77. case GL_RGB10: case GL_RGB12:
  78. case GL_RGB16:
  79. break;
  80. case GL_RGBA: case 4:
  81. case GL_RGBA2: case GL_RGBA4:
  82. case GL_RGBA8: case GL_RGBA12:
  83. case GL_RGBA16: case GL_RGB5_A1:
  84. case GL_RGB10_A2:
  85. break;
  86. case GL_ALPHA:
  87. case GL_ALPHA4: case GL_ALPHA8:
  88. case GL_ALPHA12: case GL_ALPHA16:
  89. break;
  90. case GL_INTENSITY:
  91. case GL_INTENSITY4: case GL_INTENSITY8:
  92. case GL_INTENSITY12: case GL_INTENSITY16:
  93. break;
  94. #ifdef GL_EXT_paletted_texture
  95. case GL_COLOR_INDEX1_EXT: case GL_COLOR_INDEX2_EXT:
  96. case GL_COLOR_INDEX4_EXT: case GL_COLOR_INDEX8_EXT:
  97. case GL_COLOR_INDEX12_EXT: case GL_COLOR_INDEX16_EXT:
  98. if (format != GL_COLOR_INDEX)
  99. {
  100. __glSetError(GL_INVALID_OPERATION);
  101. return NULL;
  102. }
  103. break;
  104. #endif
  105. default:
  106. goto bad_enum;
  107. }
  108. if ((border < 0) || (border > 1)) {
  109. #ifdef NT
  110. __glSetError(GL_INVALID_VALUE);
  111. return 0;
  112. #else
  113. goto bad_enum;
  114. #endif
  115. }
  116. return tex;
  117. }
  118. #ifdef GL_EXT_paletted_texture
  119. // Attempt to set the extraction function. If no palette is set,
  120. // this can't be done
  121. void __glSetPaletteLevelExtract8(__GLtexture *tex, __GLmipMapLevel *lp,
  122. GLint border)
  123. {
  124. if (tex->paletteBaseFormat == GL_RGB)
  125. {
  126. if (border)
  127. {
  128. lp->extract = __glExtractTexelPI8BGR_B;
  129. }
  130. else
  131. {
  132. lp->extract = __glExtractTexelPI8BGR;
  133. }
  134. }
  135. else if (tex->paletteBaseFormat == GL_RGBA)
  136. {
  137. if (border)
  138. {
  139. lp->extract = __glExtractTexelPI8BGRA_B;
  140. }
  141. else
  142. {
  143. lp->extract = __glExtractTexelPI8BGRA;
  144. }
  145. }
  146. #if DBG
  147. else
  148. {
  149. ASSERTOPENGL(tex->paletteBaseFormat == GL_NONE,
  150. "Unexpected paletteBaseFormat\n");
  151. }
  152. #endif
  153. }
  154. void __glSetPaletteLevelExtract16(__GLtexture *tex, __GLmipMapLevel *lp,
  155. GLint border)
  156. {
  157. if (tex->paletteBaseFormat == GL_RGB)
  158. {
  159. if (border)
  160. {
  161. lp->extract = __glExtractTexelPI16BGR_B;
  162. }
  163. else
  164. {
  165. lp->extract = __glExtractTexelPI16BGR;
  166. }
  167. }
  168. else if (tex->paletteBaseFormat == GL_RGBA)
  169. {
  170. if (border)
  171. {
  172. lp->extract = __glExtractTexelPI16BGRA_B;
  173. }
  174. else
  175. {
  176. lp->extract = __glExtractTexelPI16BGRA;
  177. }
  178. }
  179. #if DBG
  180. else
  181. {
  182. ASSERTOPENGL(tex->paletteBaseFormat == GL_NONE,
  183. "Unexpected paletteBaseFormat\n");
  184. }
  185. #endif
  186. }
  187. #endif // GL_EXT_paletted_texture
  188. static GLint ComputeTexLevelSize(__GLcontext *gc, __GLtexture *tex,
  189. __GLmipMapLevel *lp, GLint lod,
  190. GLint components, GLsizei w, GLsizei h,
  191. GLint border, GLint dim)
  192. {
  193. GLint texelStorageSize;
  194. if ((w - border*2) > gc->constants.maxTextureSize ||
  195. (h - border*2) > gc->constants.maxTextureSize)
  196. {
  197. return -1;
  198. }
  199. lp->requestedFormat = (GLenum) components;
  200. lp->redSize = 0;
  201. lp->greenSize = 0;
  202. lp->blueSize = 0;
  203. lp->alphaSize = 0;
  204. lp->luminanceSize = 0;
  205. lp->intensitySize = 0;
  206. switch (lp->requestedFormat) {
  207. case GL_LUMINANCE: case 1:
  208. case GL_LUMINANCE4: case GL_LUMINANCE8:
  209. case GL_LUMINANCE12: case GL_LUMINANCE16:
  210. lp->baseFormat = GL_LUMINANCE;
  211. lp->internalFormat = GL_LUMINANCE;
  212. lp->luminanceSize = 24;
  213. texelStorageSize = 1 * sizeof(__GLfloat);
  214. if (border) {
  215. lp->extract = __glExtractTexelL_B;
  216. } else {
  217. lp->extract = __glExtractTexelL;
  218. }
  219. break;
  220. case GL_LUMINANCE_ALPHA: case 2:
  221. case GL_LUMINANCE4_ALPHA4: case GL_LUMINANCE6_ALPHA2:
  222. case GL_LUMINANCE8_ALPHA8: case GL_LUMINANCE12_ALPHA4:
  223. case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16:
  224. lp->baseFormat = GL_LUMINANCE_ALPHA;
  225. lp->internalFormat = GL_LUMINANCE_ALPHA;
  226. lp->luminanceSize = 24;
  227. lp->alphaSize = 24;
  228. texelStorageSize = 2 * sizeof(__GLfloat);
  229. if (border) {
  230. lp->extract = __glExtractTexelLA_B;
  231. } else {
  232. lp->extract = __glExtractTexelLA;
  233. }
  234. break;
  235. case GL_RGB: case 3:
  236. case GL_R3_G3_B2: case GL_RGB4:
  237. case GL_RGB5: case GL_RGB8:
  238. lp->baseFormat = GL_RGB;
  239. lp->internalFormat = GL_BGR_EXT;
  240. lp->redSize = 8;
  241. lp->greenSize = 8;
  242. lp->blueSize = 8;
  243. // Kept as 32-bit quantities for alignment
  244. texelStorageSize = 4 * sizeof(GLubyte);
  245. if (border) {
  246. lp->extract = __glExtractTexelBGR8_B;
  247. } else {
  248. lp->extract = __glExtractTexelBGR8;
  249. }
  250. break;
  251. case GL_RGB10: case GL_RGB12:
  252. case GL_RGB16:
  253. lp->baseFormat = GL_RGB;
  254. lp->internalFormat = GL_RGB;
  255. lp->redSize = 24;
  256. lp->greenSize = 24;
  257. lp->blueSize = 24;
  258. texelStorageSize = 3 * sizeof(__GLfloat);
  259. if (border) {
  260. lp->extract = __glExtractTexelRGB_B;
  261. } else {
  262. lp->extract = __glExtractTexelRGB;
  263. }
  264. break;
  265. case GL_RGBA: case 4:
  266. case GL_RGBA2: case GL_RGBA4:
  267. case GL_RGBA8: case GL_RGB5_A1:
  268. lp->baseFormat = GL_RGBA;
  269. lp->internalFormat = GL_BGRA_EXT;
  270. lp->redSize = 8;
  271. lp->greenSize = 8;
  272. lp->blueSize = 8;
  273. lp->alphaSize = 8;
  274. texelStorageSize = 4 * sizeof(GLubyte);
  275. if (border) {
  276. lp->extract = __glExtractTexelBGRA8_B;
  277. } else {
  278. lp->extract = __glExtractTexelBGRA8;
  279. }
  280. break;
  281. case GL_RGBA12: case GL_RGBA16:
  282. case GL_RGB10_A2:
  283. lp->baseFormat = GL_RGBA;
  284. lp->internalFormat = GL_RGBA;
  285. lp->redSize = 24;
  286. lp->greenSize = 24;
  287. lp->blueSize = 24;
  288. lp->alphaSize = 24;
  289. texelStorageSize = 4 * sizeof(__GLfloat);
  290. if (border) {
  291. lp->extract = __glExtractTexelRGBA_B;
  292. } else {
  293. lp->extract = __glExtractTexelRGBA;
  294. }
  295. break;
  296. case GL_ALPHA:
  297. case GL_ALPHA4: case GL_ALPHA8:
  298. case GL_ALPHA12: case GL_ALPHA16:
  299. lp->baseFormat = GL_ALPHA;
  300. lp->internalFormat = GL_ALPHA;
  301. lp->alphaSize = 24;
  302. texelStorageSize = 1 * sizeof(__GLfloat);
  303. if (border) {
  304. lp->extract = __glExtractTexelA_B;
  305. } else {
  306. lp->extract = __glExtractTexelA;
  307. }
  308. break;
  309. case GL_INTENSITY:
  310. case GL_INTENSITY4: case GL_INTENSITY8:
  311. case GL_INTENSITY12: case GL_INTENSITY16:
  312. lp->baseFormat = GL_INTENSITY;
  313. lp->internalFormat = GL_INTENSITY;
  314. lp->intensitySize = 24;
  315. texelStorageSize = 1 * sizeof(__GLfloat);
  316. if (border) {
  317. lp->extract = __glExtractTexelI_B;
  318. } else {
  319. lp->extract = __glExtractTexelI;
  320. }
  321. break;
  322. #ifdef GL_EXT_paletted_texture
  323. case GL_COLOR_INDEX1_EXT:
  324. case GL_COLOR_INDEX2_EXT:
  325. case GL_COLOR_INDEX4_EXT:
  326. case GL_COLOR_INDEX8_EXT:
  327. // Inherit the current palette data type
  328. lp->baseFormat = tex->paletteBaseFormat;
  329. lp->internalFormat = GL_COLOR_INDEX8_EXT;
  330. texelStorageSize = sizeof(GLubyte);
  331. __glSetPaletteLevelExtract8(tex, lp, border);
  332. break;
  333. case GL_COLOR_INDEX12_EXT:
  334. case GL_COLOR_INDEX16_EXT:
  335. // Inherit the current palette data type
  336. lp->baseFormat = tex->paletteBaseFormat;
  337. lp->internalFormat = GL_COLOR_INDEX16_EXT;
  338. texelStorageSize = sizeof(GLushort);
  339. __glSetPaletteLevelExtract16(tex, lp, border);
  340. break;
  341. #endif
  342. default:
  343. break;
  344. }
  345. return (w * h * texelStorageSize);
  346. }
  347. __GLtextureBuffer *FASTCALL __glCreateProxyLevel(__GLcontext *gc,
  348. __GLtexture *tex,
  349. GLint lod, GLint components,
  350. GLsizei w, GLsizei h, GLint border,
  351. GLint dim)
  352. {
  353. __GLmipMapLevel templ, *lp = &tex->level[lod];
  354. GLint size;
  355. size = ComputeTexLevelSize(gc, tex, &templ, lod, components,
  356. w, h, border, dim);
  357. if (size < 0) {
  358. /* Proxy allocation failed */
  359. lp->width = 0;
  360. lp->height = 0;
  361. lp->border = 0;
  362. lp->requestedFormat = 0;
  363. lp->baseFormat = 0;
  364. lp->internalFormat = 0;
  365. lp->redSize = 0;
  366. lp->greenSize = 0;
  367. lp->blueSize = 0;
  368. lp->alphaSize = 0;
  369. lp->luminanceSize = 0;
  370. lp->intensitySize = 0;
  371. lp->extract = __glNopExtract;
  372. } else {
  373. /* Proxy allocation succeeded */
  374. lp->width = w;
  375. lp->height = h;
  376. lp->border = border;
  377. lp->requestedFormat = templ.requestedFormat;
  378. lp->baseFormat = templ.baseFormat;
  379. lp->internalFormat = templ.internalFormat;
  380. lp->redSize = templ.redSize;
  381. lp->greenSize = templ.greenSize;
  382. lp->blueSize = templ.blueSize;
  383. lp->alphaSize = templ.alphaSize;
  384. lp->luminanceSize = templ.luminanceSize;
  385. lp->intensitySize = templ.intensitySize;
  386. lp->extract = templ.extract;
  387. }
  388. return 0;
  389. }
  390. __GLtextureBuffer *FASTCALL __glCreateLevel(__GLcontext *gc, __GLtexture *tex,
  391. GLint lod, GLint components,
  392. GLsizei w, GLsizei h, GLint border,
  393. GLint dim)
  394. {
  395. __GLmipMapLevel templ, *lp = &tex->level[lod];
  396. GLint size;
  397. #ifdef NT
  398. __GLtextureBuffer* pbuffer;
  399. #endif
  400. size = ComputeTexLevelSize(gc, tex, &templ, lod, components,
  401. w, h, border, dim);
  402. if (size < 0) {
  403. __glSetError(GL_INVALID_VALUE);
  404. return 0;
  405. }
  406. pbuffer = (__GLtextureBuffer*)
  407. GCREALLOC(gc, lp->buffer, (size_t)size);
  408. if (!pbuffer && size != 0)
  409. GCFREE(gc, lp->buffer);
  410. lp->buffer = pbuffer;
  411. if (lp->buffer) {
  412. /* Fill in new level info */
  413. lp->width = w;
  414. lp->height = h;
  415. lp->width2 = w - border*2;
  416. lp->widthLog2 = __glIntLog2(lp->width2);
  417. lp->height2 = h - border*2;
  418. lp->heightLog2 = __glIntLog2(lp->height2);
  419. lp->width2f = lp->width2;
  420. lp->height2f = lp->height2;
  421. lp->border = border;
  422. lp->requestedFormat = templ.requestedFormat;
  423. lp->baseFormat = templ.baseFormat;
  424. lp->internalFormat = templ.internalFormat;
  425. lp->redSize = templ.redSize;
  426. lp->greenSize = templ.greenSize;
  427. lp->blueSize = templ.blueSize;
  428. lp->alphaSize = templ.alphaSize;
  429. lp->luminanceSize = templ.luminanceSize;
  430. lp->intensitySize = templ.intensitySize;
  431. lp->extract = templ.extract;
  432. } else {
  433. /* Out of memory or the texture level is being freed */
  434. lp->width = 0;
  435. lp->height = 0;
  436. lp->width2 = 0;
  437. lp->height2 = 0;
  438. lp->widthLog2 = 0;
  439. lp->heightLog2 = 0;
  440. lp->border = 0;
  441. lp->requestedFormat = 0;
  442. lp->baseFormat = 0;
  443. lp->internalFormat = 0;
  444. lp->redSize = 0;
  445. lp->greenSize = 0;
  446. lp->blueSize = 0;
  447. lp->alphaSize = 0;
  448. lp->luminanceSize = 0;
  449. lp->intensitySize = 0;
  450. lp->extract = __glNopExtract;
  451. }
  452. if (lod == 0) {
  453. tex->p = lp->heightLog2;
  454. if (lp->widthLog2 > lp->heightLog2) {
  455. tex->p = lp->widthLog2;
  456. }
  457. }
  458. return lp->buffer;
  459. }
  460. void FASTCALL __glInitTextureStore(__GLcontext *gc, __GLpixelSpanInfo *spanInfo,
  461. GLenum internalFormat)
  462. {
  463. spanInfo->dstSkipPixels = 0;
  464. spanInfo->dstSkipLines = 0;
  465. spanInfo->dstSwapBytes = GL_FALSE;
  466. spanInfo->dstLsbFirst = GL_TRUE;
  467. spanInfo->dstLineLength = spanInfo->width;
  468. switch(internalFormat) {
  469. case GL_LUMINANCE:
  470. spanInfo->dstFormat = GL_RED;
  471. spanInfo->dstType = GL_FLOAT;
  472. spanInfo->dstAlignment = 4;
  473. break;
  474. case GL_LUMINANCE_ALPHA:
  475. spanInfo->dstFormat = __GL_RED_ALPHA;
  476. spanInfo->dstType = GL_FLOAT;
  477. spanInfo->dstAlignment = 4;
  478. break;
  479. case GL_RGB:
  480. spanInfo->dstFormat = GL_RGB;
  481. spanInfo->dstType = GL_FLOAT;
  482. spanInfo->dstAlignment = 4;
  483. break;
  484. case GL_RGBA:
  485. spanInfo->dstFormat = GL_RGBA;
  486. spanInfo->dstType = GL_FLOAT;
  487. spanInfo->dstAlignment = 4;
  488. break;
  489. case GL_ALPHA:
  490. spanInfo->dstFormat = GL_ALPHA;
  491. spanInfo->dstType = GL_FLOAT;
  492. spanInfo->dstAlignment = 4;
  493. break;
  494. case GL_INTENSITY:
  495. spanInfo->dstFormat = GL_RED;
  496. spanInfo->dstType = GL_FLOAT;
  497. spanInfo->dstAlignment = 4;
  498. break;
  499. case GL_BGR_EXT:
  500. // Be a little tricky here to pad the data out
  501. // to 32 bits
  502. spanInfo->dstFormat = GL_BGRA_EXT;
  503. spanInfo->dstType = GL_UNSIGNED_BYTE;
  504. spanInfo->dstAlignment = 4;
  505. break;
  506. case GL_BGRA_EXT:
  507. spanInfo->dstFormat = GL_BGRA_EXT;
  508. spanInfo->dstType = GL_UNSIGNED_BYTE;
  509. spanInfo->dstAlignment = 4;
  510. break;
  511. #ifdef GL_EXT_paletted_texture
  512. case GL_COLOR_INDEX8_EXT:
  513. case GL_COLOR_INDEX16_EXT:
  514. spanInfo->dstFormat = GL_COLOR_INDEX;
  515. spanInfo->dstType =
  516. internalFormat == GL_COLOR_INDEX8_EXT ?
  517. GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
  518. spanInfo->dstAlignment = 1;
  519. break;
  520. #endif
  521. }
  522. }
  523. /*
  524. ** Used for extraction from textures. "packed" is set to GL_TRUE if this
  525. ** image is being pulled out of a display list, and GL_FALSE if it is
  526. ** being pulled directly out of an application.
  527. */
  528. void FASTCALL __glInitTextureUnpack(__GLcontext *gc, __GLpixelSpanInfo *spanInfo,
  529. GLint width, GLint height, GLenum format,
  530. GLenum type, const GLvoid *buf,
  531. GLenum internalFormat, GLboolean packed)
  532. {
  533. spanInfo->x = 0;
  534. spanInfo->zoomx = __glOne;
  535. spanInfo->realWidth = spanInfo->width = width;
  536. spanInfo->height = height;
  537. spanInfo->srcFormat = format;
  538. spanInfo->srcType = type;
  539. spanInfo->srcImage = buf;
  540. __glInitTextureStore(gc, spanInfo, internalFormat);
  541. __glLoadUnpackModes(gc, spanInfo, packed);
  542. }
  543. /*
  544. ** Return GL_TRUE if the given range (length or width/height) is a legal
  545. ** power of 2, taking into account the border. The range is not allowed
  546. ** to be negative either.
  547. */
  548. static GLboolean FASTCALL IsLegalRange(__GLcontext *gc, GLsizei r, GLint border)
  549. {
  550. #ifdef __GL_LINT
  551. gc = gc;
  552. #endif
  553. r -= border * 2;
  554. if ((r < 0) || (r & (r - 1))) {
  555. __glSetError(GL_INVALID_VALUE);
  556. return GL_FALSE;
  557. }
  558. return GL_TRUE;
  559. }
  560. __GLtexture *FASTCALL __glCheckTexImage1DArgs(__GLcontext *gc, GLenum target, GLint lod,
  561. GLint components, GLsizei length,
  562. GLint border, GLenum format, GLenum type)
  563. {
  564. __GLtexture *tex;
  565. /* Check arguments and get the right texture being changed */
  566. tex = CheckTexImageArgs(gc, target, lod, components, border,
  567. format, type, 1);
  568. if (!tex) {
  569. return 0;
  570. }
  571. if (!IsLegalRange(gc, length, border)) {
  572. return 0;
  573. }
  574. return tex;
  575. }
  576. __GLtexture *FASTCALL __glCheckTexImage2DArgs(__GLcontext *gc, GLenum target, GLint lod,
  577. GLint components, GLsizei w, GLsizei h,
  578. GLint border, GLenum format, GLenum type)
  579. {
  580. __GLtexture *tex;
  581. /* Check arguments and get the right texture being changed */
  582. tex = CheckTexImageArgs(gc, target, lod, components, border,
  583. format, type, 2);
  584. if (!tex) {
  585. return 0;
  586. }
  587. if (!IsLegalRange(gc, w, border)) {
  588. return 0;
  589. }
  590. if (!IsLegalRange(gc, h, border)) {
  591. return 0;
  592. }
  593. return tex;
  594. }
  595. #ifdef NT
  596. void APIPRIVATE __glim_TexImage1D(GLenum target, GLint lod,
  597. GLint components, GLsizei length,
  598. GLint border, GLenum format,
  599. GLenum type, const GLvoid *buf, GLboolean _IsDlist)
  600. #else
  601. void APIPRIVATE __glim_TexImage1D(GLenum target, GLint lod,
  602. GLint components, GLsizei length,
  603. GLint border, GLenum format,
  604. GLenum type, const GLvoid *buf)
  605. #endif
  606. {
  607. __GLtexture *tex;
  608. __GLtextureBuffer *dest;
  609. __GLpixelSpanInfo spanInfo;
  610. /*
  611. ** Validate because we use the copyImage proc which may be affected
  612. ** by the pickers.
  613. */
  614. __GL_SETUP_NOT_IN_BEGIN_VALIDATE();
  615. /* Check arguments and get the right texture being changed */
  616. tex = __glCheckTexImage1DArgs(gc, target, lod, components, length,
  617. border, format, type);
  618. if (!tex) {
  619. return;
  620. }
  621. // If we don't currently have the texture lock, take it.
  622. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc, TEXTURE_LOCK_FLAGS))
  623. {
  624. return;
  625. }
  626. /* Allocate memory for the level data */
  627. dest = (*tex->createLevel)(gc, tex, lod, components,
  628. length, 1+border*2, border, 1);
  629. /* Copy image data */
  630. if (buf && dest) {
  631. spanInfo.dstImage = dest;
  632. #ifdef NT
  633. __glInitTextureUnpack(gc, &spanInfo, length, 1, format, type, buf,
  634. tex->level[lod].internalFormat,
  635. (GLboolean) (_IsDlist ? GL_TRUE : GL_FALSE));
  636. #else
  637. __glInitTextureUnpack(gc, &spanInfo, length, 1, format, type, buf,
  638. tex->level[lod].internalFormat, GL_FALSE);
  639. #endif
  640. spanInfo.dstSkipLines += border;
  641. __glInitUnpacker(gc, &spanInfo);
  642. __glInitPacker(gc, &spanInfo);
  643. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  644. #ifdef NT
  645. __glTexPriListLoadImage(gc, GL_TEXTURE_1D);
  646. #endif
  647. }
  648. /* Might have just disabled texturing... */
  649. __GL_DELAY_VALIDATE(gc);
  650. }
  651. #ifndef NT
  652. void __gllei_TexImage1D(__GLcontext *gc, GLenum target, GLint lod,
  653. GLint components, GLsizei length, GLint border,
  654. GLenum format, GLenum type, const GLubyte *image)
  655. {
  656. __GLtexture *tex;
  657. __GLtextureBuffer *dest;
  658. __GLpixelSpanInfo spanInfo;
  659. GLuint beginMode;
  660. /*
  661. ** Validate because we use the copyImage proc which may be affected
  662. ** by the pickers.
  663. */
  664. beginMode = gc->beginMode;
  665. if (beginMode != __GL_NOT_IN_BEGIN) {
  666. if (beginMode == __GL_NEED_VALIDATE) {
  667. (*gc->procs.validate)(gc);
  668. gc->beginMode = __GL_NOT_IN_BEGIN;
  669. } else {
  670. __glSetError(GL_INVALID_OPERATION);
  671. return;
  672. }
  673. }
  674. /* Check arguments and get the right texture being changed */
  675. tex = __glCheckTexImage1DArgs(gc, target, lod, components, length,
  676. border, format, type);
  677. if (!tex) {
  678. return;
  679. }
  680. // If we don't currently have the texture lock, take it.
  681. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc, TEXTURE_LOCK_FLAGS))
  682. {
  683. return;
  684. }
  685. /* Allocate memory for the level data */
  686. dest = (*tex->createLevel)(gc, tex, lod, components,
  687. length, 1+border*2, border, 1);
  688. /* Copy image data */
  689. if (image && dest) {
  690. spanInfo.dstImage = dest;
  691. __glInitTextureUnpack(gc, &spanInfo, length, 1, format, type, image,
  692. tex->level[lod].internalFormat, GL_TRUE);
  693. spanInfo.dstSkipLines += border;
  694. __glInitUnpacker(gc, &spanInfo);
  695. __glInitPacker(gc, &spanInfo);
  696. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  697. #ifdef NT
  698. __glTexPriListLoadImage(gc, GL_TEXTURE_1D);
  699. #endif
  700. }
  701. /* Might have just disabled texturing... */
  702. __GL_DELAY_VALIDATE(gc);
  703. }
  704. #endif // !NT
  705. /************************************************************************/
  706. void APIPRIVATE __glim_TexImage2D(GLenum target, GLint lod, GLint components,
  707. GLsizei w, GLsizei h, GLint border, GLenum format,
  708. GLenum type, const GLvoid *buf, GLboolean _IsDlist)
  709. {
  710. __GLtexture *tex;
  711. __GLtextureBuffer *dest;
  712. __GLpixelSpanInfo spanInfo;
  713. /*
  714. ** Validate because we use the copyImage proc which may be affected
  715. ** by the pickers.
  716. */
  717. __GL_SETUP_NOT_IN_BEGIN_VALIDATE();
  718. /* Check arguments and get the right texture being changed */
  719. tex = __glCheckTexImage2DArgs(gc, target, lod, components, w, h,
  720. border, format, type);
  721. if (!tex) {
  722. return;
  723. }
  724. // Check for a DirectDraw texture
  725. if (target == GL_TEXTURE_2D && gc->texture.ddtex.levels > 0)
  726. {
  727. __glSetError(GL_INVALID_OPERATION);
  728. return;
  729. }
  730. // If we don't currently have the texture lock, take it.
  731. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc, TEXTURE_LOCK_FLAGS))
  732. {
  733. return;
  734. }
  735. /* Allocate memory for the level data */
  736. dest = (*tex->createLevel)(gc, tex, lod, components, w, h, border, 2);
  737. /* Copy image data */
  738. if (buf && dest) {
  739. spanInfo.dstImage = dest;
  740. #ifdef NT
  741. __glInitTextureUnpack(gc, &spanInfo, w, h, format, type, buf,
  742. (GLenum) tex->level[lod].internalFormat,
  743. (GLboolean) (_IsDlist ? GL_TRUE : GL_FALSE));
  744. #else
  745. __glInitTextureUnpack(gc, &spanInfo, w, h, format, type, buf,
  746. tex->level[lod].internalFormat, GL_FALSE);
  747. #endif
  748. __glInitUnpacker(gc, &spanInfo);
  749. __glInitPacker(gc, &spanInfo);
  750. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  751. #ifdef NT
  752. __glTexPriListLoadImage(gc, GL_TEXTURE_2D);
  753. #endif
  754. }
  755. /* Might have just disabled texturing... */
  756. __GL_DELAY_VALIDATE(gc);
  757. }
  758. #ifndef NT
  759. void __gllei_TexImage2D(__GLcontext *gc, GLenum target, GLint lod,
  760. GLint components, GLsizei w, GLsizei h,
  761. GLint border, GLenum format, GLenum type,
  762. const GLubyte *image)
  763. {
  764. __GLtexture *tex;
  765. __GLtextureBuffer *dest;
  766. __GLpixelSpanInfo spanInfo;
  767. GLuint beginMode;
  768. /*
  769. ** Validate because we use the copyImage proc which may be affected
  770. ** by the pickers.
  771. */
  772. beginMode = gc->beginMode;
  773. if (beginMode != __GL_NOT_IN_BEGIN) {
  774. if (beginMode == __GL_NEED_VALIDATE) {
  775. (*gc->procs.validate)(gc);
  776. gc->beginMode = __GL_NOT_IN_BEGIN;
  777. } else {
  778. __glSetError(GL_INVALID_OPERATION);
  779. return;
  780. }
  781. }
  782. /* Check arguments and get the right texture being changed */
  783. tex = __glCheckTexImage2DArgs(gc, target, lod, components, w, h,
  784. border, format, type);
  785. if (!tex) {
  786. return;
  787. }
  788. // If we don't currently have the texture lock, take it.
  789. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc, TEXTURE_LOCK_FLAGS))
  790. {
  791. return;
  792. }
  793. /* Allocate memory for the level data */
  794. dest = (*tex->createLevel)(gc, tex, lod, components, w, h, border, 2);
  795. /* Copy image data */
  796. if (image && dest) {
  797. spanInfo.dstImage = dest;
  798. __glInitTextureUnpack(gc, &spanInfo, w, h, format, type, image,
  799. tex->level[lod].internalFormat, GL_TRUE);
  800. __glInitUnpacker(gc, &spanInfo);
  801. __glInitPacker(gc, &spanInfo);
  802. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  803. #ifdef NT
  804. __glTexPriListLoadImage(gc, GL_TEXTURE_2D);
  805. #endif
  806. }
  807. /* Might have just disabled texturing... */
  808. __GL_DELAY_VALIDATE(gc);
  809. }
  810. #endif // !NT
  811. /***********************************************************************/
  812. static __GLtexture *CheckTexSubImageArgs(__GLcontext *gc, GLenum target,
  813. GLint lod, GLenum format,
  814. GLenum type, GLint dim)
  815. {
  816. __GLtexture *tex = __glLookUpTexture(gc, target);
  817. __GLmipMapLevel *lp;
  818. if (!tex || (target == GL_PROXY_TEXTURE_1D) ||
  819. (target == GL_PROXY_TEXTURE_2D))
  820. {
  821. bad_enum:
  822. __glSetError(GL_INVALID_ENUM);
  823. return 0;
  824. }
  825. if (tex->dim != dim) {
  826. goto bad_enum;
  827. }
  828. switch (type) {
  829. case GL_BITMAP:
  830. if (format != GL_COLOR_INDEX) goto bad_enum;
  831. case GL_BYTE:
  832. case GL_UNSIGNED_BYTE:
  833. case GL_SHORT:
  834. case GL_UNSIGNED_SHORT:
  835. case GL_INT:
  836. case GL_UNSIGNED_INT:
  837. case GL_FLOAT:
  838. break;
  839. default:
  840. goto bad_enum;
  841. }
  842. switch (format) {
  843. case GL_COLOR_INDEX: case GL_RED:
  844. case GL_GREEN: case GL_BLUE:
  845. case GL_ALPHA: case GL_RGB:
  846. case GL_RGBA: case GL_LUMINANCE:
  847. case GL_LUMINANCE_ALPHA:
  848. #ifdef GL_EXT_bgra
  849. case GL_BGRA_EXT:
  850. case GL_BGR_EXT:
  851. #endif
  852. break;
  853. default:
  854. goto bad_enum;
  855. }
  856. if ((lod < 0) || (lod >= gc->constants.maxMipMapLevel)) {
  857. __glSetError(GL_INVALID_VALUE);
  858. return 0;
  859. }
  860. #ifdef GL_EXT_paletted_texture
  861. lp = &tex->level[lod];
  862. if ((lp->internalFormat == GL_COLOR_INDEX8_EXT ||
  863. lp->internalFormat == GL_COLOR_INDEX16_EXT) &&
  864. format != GL_COLOR_INDEX)
  865. {
  866. goto bad_enum;
  867. }
  868. #endif
  869. return tex;
  870. }
  871. /*
  872. ** Used for extraction from textures. "packed" is set to GL_TRUE if this
  873. ** image is being pulled out of a display list, and GL_FALSE if it is
  874. ** being pulled directly out of an application.
  875. */
  876. void __glInitTexSubImageUnpack(__GLcontext *gc, __GLpixelSpanInfo *spanInfo,
  877. __GLmipMapLevel *lp,
  878. GLsizei xoffset, GLsizei yoffset,
  879. GLint width, GLint height, GLenum format,
  880. GLenum type, const GLvoid *buf, GLboolean packed)
  881. {
  882. spanInfo->x = 0;
  883. spanInfo->zoomx = __glOne;
  884. spanInfo->realWidth = spanInfo->width = width;
  885. spanInfo->height = height;
  886. spanInfo->srcFormat = format;
  887. spanInfo->srcType = type;
  888. spanInfo->srcImage = buf;
  889. __glLoadUnpackModes(gc, spanInfo, packed);
  890. spanInfo->dstImage = lp->buffer;
  891. spanInfo->dstSkipPixels = xoffset + lp->border;
  892. spanInfo->dstSkipLines = yoffset + lp->border;
  893. spanInfo->dstSwapBytes = GL_FALSE;
  894. spanInfo->dstLsbFirst = GL_TRUE;
  895. spanInfo->dstLineLength = lp->width;
  896. switch(lp->internalFormat) {
  897. case GL_LUMINANCE:
  898. spanInfo->dstFormat = GL_RED;
  899. spanInfo->dstType = GL_FLOAT;
  900. spanInfo->dstAlignment = 4;
  901. break;
  902. case GL_LUMINANCE_ALPHA:
  903. spanInfo->dstFormat = __GL_RED_ALPHA;
  904. spanInfo->dstType = GL_FLOAT;
  905. spanInfo->dstAlignment = 4;
  906. break;
  907. case GL_RGB:
  908. spanInfo->dstFormat = GL_RGB;
  909. spanInfo->dstType = GL_FLOAT;
  910. spanInfo->dstAlignment = 4;
  911. break;
  912. case GL_RGBA:
  913. spanInfo->dstFormat = GL_RGBA;
  914. spanInfo->dstType = GL_FLOAT;
  915. spanInfo->dstAlignment = 4;
  916. break;
  917. case GL_ALPHA:
  918. spanInfo->dstFormat = GL_ALPHA;
  919. spanInfo->dstType = GL_FLOAT;
  920. spanInfo->dstAlignment = 4;
  921. break;
  922. case GL_INTENSITY:
  923. spanInfo->dstFormat = GL_RED;
  924. spanInfo->dstType = GL_FLOAT;
  925. spanInfo->dstAlignment = 4;
  926. break;
  927. case GL_BGR_EXT:
  928. // Be a little tricky here to pad the data out to 32 bits
  929. spanInfo->dstFormat = GL_BGRA_EXT;
  930. spanInfo->dstType = GL_UNSIGNED_BYTE;
  931. spanInfo->dstAlignment = 4;
  932. break;
  933. case GL_BGRA_EXT:
  934. spanInfo->dstFormat = GL_BGRA_EXT;
  935. spanInfo->dstType = GL_UNSIGNED_BYTE;
  936. spanInfo->dstAlignment = 4;
  937. break;
  938. #ifdef GL_EXT_paletted_texture
  939. case GL_COLOR_INDEX8_EXT:
  940. case GL_COLOR_INDEX16_EXT:
  941. spanInfo->dstFormat = GL_COLOR_INDEX;
  942. spanInfo->dstType =
  943. lp->internalFormat == GL_COLOR_INDEX8_EXT ?
  944. GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
  945. spanInfo->dstAlignment = 1;
  946. break;
  947. #endif
  948. }
  949. }
  950. static GLboolean CheckTexSubImageRange(__GLcontext *gc, __GLmipMapLevel *lp,
  951. GLint xoffset, GLint yoffset,
  952. GLsizei w, GLsizei h)
  953. {
  954. #ifdef __GL_LINT
  955. gc = gc;
  956. #endif
  957. if ((w < 0) || (h < 0) ||
  958. (xoffset < -lp->border) || (xoffset+w > lp->width-lp->border) ||
  959. (yoffset < -lp->border) || (yoffset+h > lp->height-lp->border))
  960. {
  961. __glSetError(GL_INVALID_VALUE);
  962. return GL_FALSE;
  963. }
  964. return GL_TRUE;
  965. }
  966. __GLtexture *__glCheckTexSubImage1DArgs(__GLcontext *gc, GLenum target,
  967. GLint lod,
  968. GLint xoffset, GLint length,
  969. GLenum format, GLenum type)
  970. {
  971. __GLtexture *tex;
  972. __GLmipMapLevel *lp;
  973. /* Check arguments and get the right texture being changed */
  974. tex = CheckTexSubImageArgs(gc, target, lod, format, type, 1);
  975. if (!tex) {
  976. return 0;
  977. }
  978. lp = &tex->level[lod];
  979. if (!CheckTexSubImageRange(gc, lp, xoffset, 0, length, 1)) {
  980. return 0;
  981. }
  982. return tex;
  983. }
  984. __GLtexture *__glCheckTexSubImage2DArgs(__GLcontext *gc, GLenum target,
  985. GLint lod,
  986. GLint xoffset, GLint yoffset,
  987. GLsizei w, GLsizei h,
  988. GLenum format, GLenum type)
  989. {
  990. __GLtexture *tex;
  991. __GLmipMapLevel *lp;
  992. /* Check arguments and get the right texture being changed */
  993. tex = CheckTexSubImageArgs(gc, target, lod, format, type, 2);
  994. if (!tex) {
  995. return 0;
  996. }
  997. lp = &tex->level[lod];
  998. if (!CheckTexSubImageRange(gc, lp, xoffset, yoffset, w, h)) {
  999. return 0;
  1000. }
  1001. return tex;
  1002. }
  1003. #ifdef NT
  1004. void APIPRIVATE __glim_TexSubImage1D(GLenum target, GLint lod,
  1005. GLint xoffset, GLint length,
  1006. GLenum format, GLenum type, const GLvoid *buf,
  1007. GLboolean _IsDlist)
  1008. #else
  1009. void APIPRIVATE __glim_TexSubImage1D(GLenum target, GLint lod,
  1010. GLint xoffset, GLint length,
  1011. GLenum format, GLenum type, const GLvoid *buf)
  1012. #endif
  1013. {
  1014. __GLtexture *tex;
  1015. __GLmipMapLevel *lp;
  1016. __GLpixelSpanInfo spanInfo;
  1017. /*
  1018. ** Validate because we use the copyImage proc which may be affected
  1019. ** by the pickers.
  1020. */
  1021. __GL_SETUP_NOT_IN_BEGIN_VALIDATE();
  1022. /* Check arguments and get the right texture level being changed */
  1023. tex = __glCheckTexSubImage1DArgs(gc, target, lod, xoffset, length,
  1024. format, type);
  1025. if (!tex) {
  1026. return;
  1027. }
  1028. lp = &tex->level[lod];
  1029. if (lp->buffer == NULL) {
  1030. __glSetError(GL_INVALID_OPERATION);
  1031. return;
  1032. }
  1033. // If we don't currently have the texture lock, take it.
  1034. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc, TEXTURE_LOCK_FLAGS))
  1035. {
  1036. return;
  1037. }
  1038. /* Copy sub-image data */
  1039. #ifdef NT
  1040. __glInitTexSubImageUnpack(gc, &spanInfo, lp, xoffset, 0, length, 1,
  1041. format, type, buf,
  1042. (GLboolean) (_IsDlist ? GL_TRUE : GL_FALSE));
  1043. #else
  1044. __glInitTexSubImageUnpack(gc, &spanInfo, lp, xoffset, 0, length, 1,
  1045. format, type, buf, GL_FALSE);
  1046. #endif
  1047. spanInfo.dstSkipLines += lp->border;
  1048. __glInitUnpacker(gc, &spanInfo);
  1049. __glInitPacker(gc, &spanInfo);
  1050. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  1051. #ifdef NT
  1052. __glTexPriListLoadSubImage(gc, GL_TEXTURE_1D, lod, xoffset, 0,
  1053. length, 1);
  1054. #endif
  1055. }
  1056. #ifndef NT
  1057. void __gllei_TexSubImage1D(__GLcontext *gc, GLenum target, GLint lod,
  1058. GLint xoffset, GLint length,
  1059. GLenum format, GLenum type, const GLubyte *image)
  1060. {
  1061. __GLtexture *tex;
  1062. __GLmipMapLevel *lp;
  1063. __GLpixelSpanInfo spanInfo;
  1064. GLuint beginMode;
  1065. /*
  1066. ** Validate because we use the copyImage proc which may be affected
  1067. ** by the pickers.
  1068. */
  1069. beginMode = gc->beginMode;
  1070. if (beginMode != __GL_NOT_IN_BEGIN) {
  1071. if (beginMode == __GL_NEED_VALIDATE) {
  1072. (*gc->procs.validate)(gc);
  1073. gc->beginMode = __GL_NOT_IN_BEGIN;
  1074. } else {
  1075. __glSetError(GL_INVALID_OPERATION);
  1076. return;
  1077. }
  1078. }
  1079. /* Check arguments and get the right texture level being changed */
  1080. tex = __glCheckTexSubImage1DArgs(gc, target, lod, xoffset, length,
  1081. format, type);
  1082. if (!tex) {
  1083. return;
  1084. }
  1085. lp = &tex->level[lod];
  1086. if (lp->buffer == NULL) {
  1087. __glSetError(GL_INVALID_OPERATION);
  1088. return;
  1089. }
  1090. // If we don't currently have the texture lock, take it.
  1091. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc, TEXTURE_LOCK_FLAGS))
  1092. {
  1093. return;
  1094. }
  1095. /* Copy sub-image data */
  1096. __glInitTexSubImageUnpack(gc, &spanInfo, lp, xoffset, 0, length, 1,
  1097. format, type, image, GL_TRUE);
  1098. spanInfo.dstSkipLines += lp->border;
  1099. __glInitUnpacker(gc, &spanInfo);
  1100. __glInitPacker(gc, &spanInfo);
  1101. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  1102. #ifdef NT
  1103. __glTexPriListLoadSubImage(gc, GL_TEXTURE_1D, lod, xoffset, 0,
  1104. length, 1);
  1105. #endif
  1106. }
  1107. #endif // !NT
  1108. #ifdef NT
  1109. void APIPRIVATE __glim_TexSubImage2D(GLenum target, GLint lod,
  1110. GLint xoffset, GLint yoffset,
  1111. GLsizei w, GLsizei h, GLenum format,
  1112. GLenum type, const GLvoid *buf, GLboolean _IsDlist)
  1113. #else
  1114. void APIPRIVATE __glim_TexSubImage2D(GLenum target, GLint lod,
  1115. GLint xoffset, GLint yoffset,
  1116. GLsizei w, GLsizei h, GLenum format,
  1117. GLenum type, const GLvoid *buf)
  1118. #endif
  1119. {
  1120. __GLtexture *tex;
  1121. __GLmipMapLevel *lp;
  1122. __GLpixelSpanInfo spanInfo;
  1123. /*
  1124. ** Validate because we use the copyImage proc which may be affected
  1125. ** by the pickers.
  1126. */
  1127. __GL_SETUP_NOT_IN_BEGIN_VALIDATE();
  1128. /* Check arguments and get the right texture level being changed */
  1129. tex = __glCheckTexSubImage2DArgs(gc, target, lod, xoffset, yoffset, w, h,
  1130. format, type);
  1131. if (!tex) {
  1132. return;
  1133. }
  1134. lp = &tex->level[lod];
  1135. if (lp->buffer == NULL) {
  1136. __glSetError(GL_INVALID_OPERATION);
  1137. return;
  1138. }
  1139. // If we don't currently have the texture lock, take it.
  1140. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc, TEXTURE_LOCK_FLAGS))
  1141. {
  1142. return;
  1143. }
  1144. /* Copy sub-image data */
  1145. #ifdef NT
  1146. __glInitTexSubImageUnpack(gc, &spanInfo, lp, xoffset, yoffset, w, h,
  1147. format, type, buf,
  1148. (GLboolean) (_IsDlist ? GL_TRUE : GL_FALSE));
  1149. #else
  1150. __glInitTexSubImageUnpack(gc, &spanInfo, lp, xoffset, yoffset, w, h,
  1151. format, type, buf, GL_FALSE);
  1152. #endif
  1153. __glInitUnpacker(gc, &spanInfo);
  1154. __glInitPacker(gc, &spanInfo);
  1155. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  1156. #ifdef NT
  1157. __glTexPriListLoadSubImage(gc, GL_TEXTURE_2D, lod, xoffset, yoffset,
  1158. w, h);
  1159. #endif
  1160. }
  1161. #ifndef NT
  1162. void __gllei_TexSubImage2D(__GLcontext *gc, GLenum target, GLint lod,
  1163. GLint xoffset, GLint yoffset,
  1164. GLsizei w, GLsizei h, GLenum format, GLenum type,
  1165. const GLubyte *image)
  1166. {
  1167. __GLtexture *tex;
  1168. __GLmipMapLevel *lp;
  1169. __GLpixelSpanInfo spanInfo;
  1170. GLuint beginMode;
  1171. /*
  1172. ** Validate because we use the copyImage proc which may be affected
  1173. ** by the pickers.
  1174. */
  1175. beginMode = gc->beginMode;
  1176. if (beginMode != __GL_NOT_IN_BEGIN) {
  1177. if (beginMode == __GL_NEED_VALIDATE) {
  1178. (*gc->procs.validate)(gc);
  1179. gc->beginMode = __GL_NOT_IN_BEGIN;
  1180. } else {
  1181. __glSetError(GL_INVALID_OPERATION);
  1182. return;
  1183. }
  1184. }
  1185. /* Check arguments and get the right texture level being changed */
  1186. tex = __glCheckTexSubImage2DArgs(gc, target, lod, xoffset, yoffset, w, h,
  1187. format, type);
  1188. if (!tex) {
  1189. return;
  1190. }
  1191. lp = &tex->level[lod];
  1192. if (lp->buffer == NULL) {
  1193. __glSetError(GL_INVALID_OPERATION);
  1194. return;
  1195. }
  1196. // If we don't currently have the texture lock, take it.
  1197. if (!glsrvLazyGrabSurfaces((__GLGENcontext *)gc, TEXTURE_LOCK_FLAGS))
  1198. {
  1199. return;
  1200. }
  1201. /* Copy sub-image data */
  1202. __glInitTexSubImageUnpack(gc, &spanInfo, lp, xoffset, yoffset, w, h,
  1203. format, type, image, GL_TRUE);
  1204. __glInitUnpacker(gc, &spanInfo);
  1205. __glInitPacker(gc, &spanInfo);
  1206. (*gc->procs.copyImage)(gc, &spanInfo, GL_TRUE);
  1207. #ifdef NT
  1208. __glTexPriListLoadSubImage(gc, GL_TEXTURE_2D, lod, xoffset, yoffset,
  1209. w, h);
  1210. #endif
  1211. }
  1212. #endif // !NT
  1213. /************************************************************************/
  1214. // Routine to set up all the correct pixel modes for a straight data
  1215. // copy. Preserves state for later shutoff
  1216. typedef struct _StraightCopyStorage
  1217. {
  1218. __GLpixelPackMode pack;
  1219. __GLpixelUnpackMode unpack;
  1220. __GLpixelTransferMode transfer;
  1221. } StraightCopyStorage;
  1222. void StartStraightCopy(__GLcontext *gc, StraightCopyStorage *state)
  1223. {
  1224. state->pack = gc->state.pixel.packModes;
  1225. state->unpack = gc->state.pixel.unpackModes;
  1226. state->transfer = gc->state.pixel.transferMode;
  1227. gc->state.pixel.packModes.swapEndian = GL_FALSE;
  1228. gc->state.pixel.packModes.lsbFirst = GL_FALSE;
  1229. gc->state.pixel.packModes.lineLength = 0;
  1230. gc->state.pixel.packModes.skipLines = 0;
  1231. gc->state.pixel.packModes.skipPixels = 0;
  1232. gc->state.pixel.packModes.alignment = 4;
  1233. gc->state.pixel.unpackModes.swapEndian = GL_FALSE;
  1234. gc->state.pixel.unpackModes.lsbFirst = GL_FALSE;
  1235. gc->state.pixel.unpackModes.lineLength = 0;
  1236. gc->state.pixel.unpackModes.skipLines = 0;
  1237. gc->state.pixel.unpackModes.skipPixels = 0;
  1238. gc->state.pixel.unpackModes.alignment = 4;
  1239. gc->state.pixel.transferMode.r_scale = 1.0f;
  1240. gc->state.pixel.transferMode.g_scale = 1.0f;
  1241. gc->state.pixel.transferMode.b_scale = 1.0f;
  1242. gc->state.pixel.transferMode.a_scale = 1.0f;
  1243. gc->state.pixel.transferMode.d_scale = 1.0f;
  1244. gc->state.pixel.transferMode.r_bias = 0.0f;
  1245. gc->state.pixel.transferMode.g_bias = 0.0f;
  1246. gc->state.pixel.transferMode.b_bias = 0.0f;
  1247. gc->state.pixel.transferMode.a_bias = 0.0f;
  1248. gc->state.pixel.transferMode.d_bias = 0.0f;
  1249. gc->state.pixel.transferMode.zoomX = 1.0f;
  1250. gc->state.pixel.transferMode.zoomY = 1.0f;
  1251. gc->state.pixel.transferMode.indexShift = 0;
  1252. gc->state.pixel.transferMode.indexOffset = 0;
  1253. gc->state.pixel.transferMode.mapColor = GL_FALSE;
  1254. gc->state.pixel.transferMode.mapStencil = GL_FALSE;
  1255. // Many states have changed so force a repick
  1256. __GL_DELAY_VALIDATE(gc);
  1257. }
  1258. void EndStraightCopy(__GLcontext *gc, StraightCopyStorage *state)
  1259. {
  1260. gc->state.pixel.packModes = state->pack;
  1261. gc->state.pixel.unpackModes = state->unpack;
  1262. gc->state.pixel.transferMode = state->transfer;
  1263. // Many states have changed so force a repick
  1264. __GL_DELAY_VALIDATE(gc);
  1265. }
  1266. void APIPRIVATE __glim_CopyTexImage1D(GLenum target, GLint level,
  1267. GLenum internalformat, GLint x, GLint y,
  1268. GLsizei width, GLint border)
  1269. {
  1270. GLubyte *pixels;
  1271. GLenum format, type;
  1272. StraightCopyStorage state;
  1273. __GL_SETUP();
  1274. if (target != GL_TEXTURE_1D ||
  1275. (internalformat >= 1 && internalformat <= 4))
  1276. {
  1277. __glSetError(GL_INVALID_ENUM);
  1278. return;
  1279. }
  1280. // Use BGRA format because that matches our internal texture format
  1281. format = GL_BGRA_EXT;
  1282. type = GL_UNSIGNED_BYTE;
  1283. // Allocate space for pixel data, read pixels into it from the
  1284. // frame buffer and then do a TexImage
  1285. pixels = (GLubyte *)GCALLOC(gc, width*4);
  1286. if (pixels == NULL)
  1287. {
  1288. return;
  1289. }
  1290. StartStraightCopy(gc, &state);
  1291. // __glim_ReadPixels will take the texture lock.
  1292. __glim_ReadPixels(x, y, width, 1, format, type, pixels);
  1293. __glim_TexImage1D(target, level, internalformat,
  1294. width, border, format, type,
  1295. pixels, GL_FALSE);
  1296. EndStraightCopy(gc, &state);
  1297. GCFREE(gc, pixels);
  1298. }
  1299. void APIPRIVATE __glim_CopyTexImage2D(GLenum target, GLint level,
  1300. GLenum internalformat, GLint x, GLint y,
  1301. GLsizei width, GLsizei height, GLint border)
  1302. {
  1303. GLubyte *pixels;
  1304. GLenum format, type;
  1305. StraightCopyStorage state;
  1306. __GL_SETUP();
  1307. if (target != GL_TEXTURE_2D ||
  1308. (internalformat >= 1 && internalformat <= 4))
  1309. {
  1310. __glSetError(GL_INVALID_ENUM);
  1311. return;
  1312. }
  1313. // Check for a DirectDraw texture
  1314. if (target == GL_TEXTURE_2D && gc->texture.ddtex.levels > 0)
  1315. {
  1316. __glSetError(GL_INVALID_OPERATION);
  1317. return;
  1318. }
  1319. // Use BGRA format because that matches our internal texture format
  1320. format = GL_BGRA_EXT;
  1321. type = GL_UNSIGNED_BYTE;
  1322. // Allocate space for pixel data, read pixels into it from the
  1323. // frame buffer and then do a TexImage
  1324. pixels = (GLubyte *)GCALLOC(gc, width*height*4);
  1325. if (pixels == NULL)
  1326. {
  1327. return;
  1328. }
  1329. StartStraightCopy(gc, &state);
  1330. // __glim_ReadPixels will take the texture lock.
  1331. __glim_ReadPixels(x, y, width, height, format, type, pixels);
  1332. __glim_TexImage2D(target, level, internalformat,
  1333. width, height, border, format,
  1334. type, pixels, GL_FALSE);
  1335. EndStraightCopy(gc, &state);
  1336. GCFREE(gc, pixels);
  1337. }
  1338. void APIPRIVATE __glim_CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset,
  1339. GLint x, GLint y, GLsizei width)
  1340. {
  1341. GLubyte *pixels;
  1342. GLenum format, type;
  1343. StraightCopyStorage state;
  1344. __GL_SETUP();
  1345. if (target != GL_TEXTURE_1D)
  1346. {
  1347. __glSetError(GL_INVALID_ENUM);
  1348. return;
  1349. }
  1350. // Use BGRA format because that matches our internal texture format
  1351. format = GL_BGRA_EXT;
  1352. type = GL_UNSIGNED_BYTE;
  1353. // Allocate space for pixel data, read pixels into it from the
  1354. // frame buffer and then do a TexImage
  1355. pixels = (GLubyte *)GCALLOC(gc, width*4);
  1356. if (pixels == NULL)
  1357. {
  1358. return;
  1359. }
  1360. StartStraightCopy(gc, &state);
  1361. // __glim_ReadPixels will take the texture lock.
  1362. __glim_ReadPixels(x, y, width, 1, format, type, pixels);
  1363. __glim_TexSubImage1D(target, level, xoffset,
  1364. width, format, type,
  1365. pixels, GL_FALSE);
  1366. EndStraightCopy(gc, &state);
  1367. GCFREE(gc, pixels);
  1368. }
  1369. void APIPRIVATE __glim_CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset,
  1370. GLint yoffset, GLint x, GLint y,
  1371. GLsizei width, GLsizei height)
  1372. {
  1373. GLubyte *pixels;
  1374. GLenum format, type;
  1375. StraightCopyStorage state;
  1376. __GL_SETUP();
  1377. if (target != GL_TEXTURE_2D)
  1378. {
  1379. __glSetError(GL_INVALID_ENUM);
  1380. return;
  1381. }
  1382. // Use BGRA format because that matches our internal texture format
  1383. format = GL_BGRA_EXT;
  1384. type = GL_UNSIGNED_BYTE;
  1385. // Allocate space for pixel data, read pixels into it from the
  1386. // frame buffer and then do a TexImage
  1387. pixels = (GLubyte *)GCALLOC(gc, width*height*4);
  1388. if (pixels == NULL)
  1389. {
  1390. return;
  1391. }
  1392. StartStraightCopy(gc, &state);
  1393. // __glim_ReadPixels will take the texture lock.
  1394. __glim_ReadPixels(x, y, width, height, format, type, pixels);
  1395. __glim_TexSubImage2D(target, level, xoffset,
  1396. yoffset, width, height,
  1397. format, type, pixels, GL_FALSE);
  1398. EndStraightCopy(gc, &state);
  1399. GCFREE(gc, pixels);
  1400. }