VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_teximage.c@ 16970

Last change on this file since 16970 was 16969, checked in by vboxsync, 16 years ago

crOpenGL: don't allocate memory for textures on host side (#3461)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 46.6 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7
8#include "state.h"
9#include "state/cr_statetypes.h"
10#include "state/cr_texture.h"
11#include "cr_pixeldata.h"
12#include "cr_string.h"
13#include "cr_mem.h"
14#include "cr_version.h"
15#include "state_internals.h"
16
17
18
19static int
20bitcount(int value)
21{
22 int bits = 0;
23 for (; value > 0; value >>= 1) {
24 if (value & 0x1)
25 bits++;
26 }
27 return bits;
28}
29
30
31/**
32 * Return 1 if the target is a proxy target, 0 otherwise.
33 */
34static GLboolean
35IsProxyTarget(GLenum target)
36{
37 return (target == GL_PROXY_TEXTURE_1D ||
38 target == GL_PROXY_TEXTURE_2D ||
39 target == GL_PROXY_TEXTURE_3D ||
40 target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
41 target == GL_PROXY_TEXTURE_CUBE_MAP);
42}
43
44
45/**
46 * Test if a texture width, height or depth is legal.
47 * It must be true that 0 <= size <= max.
48 * Furthermore, if the ARB_texture_non_power_of_two extension isn't
49 * present, size must also be a power of two.
50 */
51static GLboolean
52isLegalSize(CRContext *g, GLsizei size, GLsizei max)
53{
54 if (size < 0 || size > max)
55 return GL_FALSE;
56 if (!g->extensions.ARB_texture_non_power_of_two) {
57 /* check for power of two */
58 if (size > 0 && bitcount(size) != 1)
59 return GL_FALSE;
60 }
61 return GL_TRUE;
62}
63
64
65/**
66 * Return the max legal texture level parameter for the given target.
67 */
68static GLint
69MaxTextureLevel(CRContext *g, GLenum target)
70{
71 CRTextureState *t = &(g->texture);
72 switch (target) {
73 case GL_TEXTURE_1D:
74 case GL_PROXY_TEXTURE_1D:
75 case GL_TEXTURE_2D:
76 case GL_PROXY_TEXTURE_2D:
77 return t->maxLevel;
78 case GL_TEXTURE_3D:
79 case GL_PROXY_TEXTURE_3D:
80 return t->max3DLevel;
81 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
82 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
83 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
84 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
85 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
86 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
87 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
88 return t->maxCubeMapLevel;
89 case GL_TEXTURE_RECTANGLE_NV:
90 case GL_PROXY_TEXTURE_RECTANGLE_NV:
91 return t->maxRectLevel;
92 default:
93 return 0;
94 }
95}
96
97
98/**
99 * If GL_GENERATE_MIPMAP_SGIS is true and we modify the base level texture
100 * image we have to finish the mipmap.
101 * All we really have to do is fill in the width/height/format/etc for the
102 * remaining image levels. The image data doesn't matter here - the back-
103 * end OpenGL library will fill those in.
104 */
105static void
106generate_mipmap(CRTextureObj *tobj, GLenum target)
107{
108 CRTextureLevel *levels;
109 GLint level, width, height, depth;
110
111 if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
112 target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
113 levels = tobj->level[target - GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB];
114 }
115 else {
116 levels = tobj->level[0];
117 }
118
119 width = levels[tobj->baseLevel].width;
120 height = levels[tobj->baseLevel].height;
121 depth = levels[tobj->baseLevel].depth;
122
123 for (level = tobj->baseLevel + 1; level <= tobj->maxLevel; level++)
124 {
125 if (width > 1)
126 width /= 2;
127 if (height > 1)
128 height /= 2;
129 if (depth > 1)
130 depth /= 2;
131 levels[level].width = width;
132 levels[level].height = height;
133 levels[level].depth = depth;
134 levels[level].internalFormat = levels[tobj->baseLevel].internalFormat;
135 levels[level].format = levels[tobj->baseLevel].format;
136 levels[level].type = levels[tobj->baseLevel].type;
137#ifdef CR_ARB_texture_compression
138 levels[level].compressed = levels[tobj->baseLevel].compressed;
139#endif
140 levels[level].texFormat = levels[tobj->baseLevel].texFormat;
141 if (width == 1 && height == 1 && depth == 1)
142 break;
143 }
144
145 /* Set this flag so when we do the state diff, we enable GENERATE_MIPMAP
146 * prior to calling diff.TexImage().
147 */
148 levels[tobj->baseLevel].generateMipmap = GL_TRUE;
149}
150
151
152/**
153 * Given a texture target and level, return pointers to the corresponding
154 * texture object and texture image level.
155 */
156void
157crStateGetTextureObjectAndImage(CRContext *g, GLenum texTarget, GLint level,
158 CRTextureObj **obj, CRTextureLevel **img)
159{
160 CRTextureState *t = &(g->texture);
161 CRTextureUnit *unit = t->unit + t->curTextureUnit;
162
163 switch (texTarget) {
164 case GL_TEXTURE_1D:
165 *obj = unit->currentTexture1D;
166 *img = unit->currentTexture1D->level[0] + level;
167 return;
168 case GL_PROXY_TEXTURE_1D:
169 *obj = &(t->proxy1D);
170 *img = t->proxy1D.level[0] + level;
171 return;
172 case GL_TEXTURE_2D:
173 *obj = unit->currentTexture2D;
174 *img = unit->currentTexture2D->level[0] + level;
175 return;
176 case GL_PROXY_TEXTURE_2D:
177 *obj = &(t->proxy2D);
178 *img = t->proxy2D.level[0] + level;
179 return;
180 case GL_TEXTURE_3D:
181 *obj = unit->currentTexture3D;
182 *img = unit->currentTexture3D->level[0] + level;
183 return;
184 case GL_PROXY_TEXTURE_3D:
185 *obj = &(t->proxy3D);
186 *img = t->proxy3D.level[0] + level;
187 return;
188 default:
189 /* fall-through */
190 ;
191 }
192
193#ifdef CR_NV_texture_rectangle
194 if (g->extensions.NV_texture_rectangle) {
195 switch (texTarget) {
196 case GL_PROXY_TEXTURE_RECTANGLE_NV:
197 *obj = &(t->proxyRect);
198 *img = t->proxyRect.level[0] + level;
199 return;
200 case GL_TEXTURE_RECTANGLE_NV:
201 *obj = unit->currentTextureRect;
202 *img = unit->currentTextureRect->level[0] + level;
203 return;
204 default:
205 /* fall-through */
206 ;
207 }
208 }
209#endif
210
211#ifdef CR_ARB_texture_cube_map
212 if (g->extensions.ARB_texture_cube_map) {
213 switch (texTarget) {
214 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
215 *obj = &(t->proxyCubeMap);
216 *img = t->proxyCubeMap.level[0] + level;
217 return;
218 case GL_TEXTURE_CUBE_MAP_ARB:
219 *obj = unit->currentTextureCubeMap;
220 *img = NULL;
221 return;
222 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
223 *obj = unit->currentTextureCubeMap;
224 *img = unit->currentTextureCubeMap->level[0] + level;
225 return;
226 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
227 *obj = unit->currentTextureCubeMap;
228 *img = unit->currentTextureCubeMap->level[1] + level;
229 return;
230 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
231 *obj = unit->currentTextureCubeMap;
232 *img = unit->currentTextureCubeMap->level[2] + level;
233 return;
234 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
235 *obj = unit->currentTextureCubeMap;
236 *img = unit->currentTextureCubeMap->level[3] + level;
237 return;
238 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
239 *obj = unit->currentTextureCubeMap;
240 *img = unit->currentTextureCubeMap->level[4] + level;
241 return;
242 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
243 *obj = unit->currentTextureCubeMap;
244 *img = unit->currentTextureCubeMap->level[5] + level;
245 return;
246 default:
247 /* fall-through */
248 ;
249 }
250 }
251#endif
252
253 *obj = NULL;
254 *img = NULL;
255}
256
257
258/**
259 * Do parameter error checking for glTexImagexD functions.
260 * We'll call crStateError if we detect any errors, unless it's a proxy target.
261 * Return GL_TRUE if any errors, GL_FALSE if no errors.
262 */
263static GLboolean
264ErrorCheckTexImage(GLuint dims, GLenum target, GLint level,
265 GLsizei width, GLsizei height, GLsizei depth, GLint border)
266{
267 CRContext *g = GetCurrentContext();
268
269 if (g->current.inBeginEnd)
270 {
271 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
272 "glTexImage%uD called in Begin/End", dims);
273 return GL_TRUE;
274 }
275
276 /*
277 * Test target
278 */
279 switch (target)
280 {
281 case GL_TEXTURE_1D:
282 case GL_PROXY_TEXTURE_1D:
283 if (dims != 1) {
284 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
285 "glTexImage(invalid target=0x%x)", target);
286 return GL_TRUE;
287 }
288 break;
289 case GL_TEXTURE_2D:
290 case GL_PROXY_TEXTURE_2D:
291 if (dims != 2) {
292 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
293 "glTexImage(invalid target=0x%x)", target);
294 return GL_TRUE;
295 }
296 break;
297 case GL_TEXTURE_3D:
298 case GL_PROXY_TEXTURE_3D:
299 if (dims != 3) {
300 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
301 "glTexImage(invalid target=0x%x)", target);
302 return GL_TRUE;
303 }
304 break;
305#ifdef CR_NV_texture_rectangle
306 case GL_TEXTURE_RECTANGLE_NV:
307 case GL_PROXY_TEXTURE_RECTANGLE_NV:
308 if (dims != 2 || !g->extensions.NV_texture_rectangle) {
309 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
310 "glTexImage2D(invalid target=0x%x)", target);
311 return GL_TRUE;
312 }
313 break;
314#endif
315#ifdef CR_ARB_texture_cube_map
316 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
317 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
318 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
319 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
320 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
321 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
322 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
323 if (dims != 2 || !g->extensions.ARB_texture_cube_map) {
324 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
325 "glTexImage2D(invalid target=0x%x)", target);
326 return GL_TRUE;
327 }
328 break;
329#endif
330 default:
331 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
332 "glTexImage%uD(invalid target=0x%x)", dims, target);
333 return GL_TRUE;
334 }
335
336 /*
337 * Test level
338 */
339 if (level < 0 || level > MaxTextureLevel(g, target)) {
340 if (!IsProxyTarget(target))
341 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
342 "glTexImage%uD(level=%d)", dims, level);
343 return GL_TRUE;
344 }
345
346 /*
347 * Test border
348 */
349 if (border != 0 && border != 1) {
350 if (!IsProxyTarget(target))
351 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
352 "glTexImage%uD(border=%d)", dims, border);
353 return GL_TRUE;
354 }
355
356 if ((target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
357 target == GL_TEXTURE_RECTANGLE_NV) && border != 0) {
358 if (!IsProxyTarget(target))
359 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
360 "glTexImage2D(border=%d)", border);
361 return GL_TRUE;
362 }
363
364 /*
365 * Test width, height, depth
366 */
367 if (target == GL_PROXY_TEXTURE_1D || target == GL_TEXTURE_1D) {
368 if (!isLegalSize(g, width - 2 * border, g->limits.maxTextureSize)) {
369 if (!IsProxyTarget(target))
370 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
371 "glTexImage1D(width=%d)", width);
372 return GL_TRUE;
373 }
374 }
375 else if (target == GL_PROXY_TEXTURE_2D || target == GL_TEXTURE_2D) {
376 if (!isLegalSize(g, width - 2 * border, g->limits.maxTextureSize) ||
377 !isLegalSize(g, height - 2 * border, g->limits.maxTextureSize)) {
378 if (!IsProxyTarget(target))
379 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
380 "glTexImage2D(width=%d, height=%d)", width, height);
381 return GL_TRUE;
382 }
383 }
384 else if (target == GL_PROXY_TEXTURE_3D || target == GL_TEXTURE_3D) {
385 if (!isLegalSize(g, width - 2 * border, g->limits.max3DTextureSize) ||
386 !isLegalSize(g, height - 2 * border, g->limits.max3DTextureSize) ||
387 !isLegalSize(g, depth - 2 * border, g->limits.max3DTextureSize)) {
388 if (!IsProxyTarget(target))
389 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
390 "glTexImage3D(width=%d, height=%d, depth=%d)",
391 width, height, depth);
392 return GL_TRUE;
393 }
394 }
395 else if (target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
396 target == GL_TEXTURE_RECTANGLE_NV) {
397 if (width < 0 || width > (int) g->limits.maxRectTextureSize ||
398 height < 0 || height > (int) g->limits.maxRectTextureSize) {
399 if (!IsProxyTarget(target))
400 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
401 "glTexImage2D(width=%d, height=%d)", width, height);
402 return GL_TRUE;
403 }
404 }
405 else {
406 /* cube map */
407 if (!isLegalSize(g, width - 2*border, g->limits.maxCubeMapTextureSize) ||
408 !isLegalSize(g, height - 2*border, g->limits.maxCubeMapTextureSize) ||
409 width != height) {
410 if (!IsProxyTarget(target))
411 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
412 "glTexImage2D(width=%d, height=%d)", width, height);
413 return GL_TRUE;
414 }
415 }
416
417 /* OK, no errors */
418 return GL_FALSE;
419}
420
421
422/**
423 * Do error check for glTexSubImage() functions.
424 * We'll call crStateError if we detect any errors.
425 * Return GL_TRUE if any errors, GL_FALSE if no errors.
426 */
427static GLboolean
428ErrorCheckTexSubImage(GLuint dims, GLenum target, GLint level,
429 GLint xoffset, GLint yoffset, GLint zoffset,
430 GLsizei width, GLsizei height, GLsizei depth)
431{
432 CRContext *g = GetCurrentContext();
433 CRTextureObj *tobj;
434 CRTextureLevel *tl;
435
436 if (g->current.inBeginEnd) {
437 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
438 "glTexSubImage%uD called in Begin/End", dims);
439 return GL_TRUE;
440 }
441
442 if (dims == 1) {
443 if (target != GL_TEXTURE_1D) {
444 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
445 "glTexSubImage1D(target=0x%x)", target);
446 return GL_TRUE;
447 }
448 }
449 else if (dims == 2) {
450 if (target != GL_TEXTURE_2D &&
451 target != GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
452 target != GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB &&
453 target != GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB &&
454 target != GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB &&
455 target != GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB &&
456 target != GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB &&
457 target != GL_TEXTURE_RECTANGLE_NV) {
458 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
459 "glTexSubImage2D(target=0x%x)", target);
460 return GL_TRUE;
461 }
462 }
463 else if (dims == 3) {
464 if (target != GL_TEXTURE_3D) {
465 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
466 "glTexSubImage3D(target=0x%x)", target);
467 return GL_TRUE;
468 }
469 }
470
471 /* test level */
472 if (level < 0 || level > MaxTextureLevel(g, target)) {
473 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
474 "glTexSubImage%uD(level=%d)", dims, level);
475 return GL_TRUE;
476 }
477
478 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
479 if (!tobj || !tl) {
480 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
481 "glTexSubImage%uD(target or level)", dims);
482 return GL_TRUE;
483 }
484
485 /* test x/y/zoffset and size */
486 if (xoffset < -tl->border || xoffset + width > tl->width) {
487 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
488 "glTexSubImage%uD(xoffset=%d + width=%d > %d)",
489 dims, xoffset, width, tl->width);
490 return GL_TRUE;
491 }
492 if (dims > 1 && (yoffset < -tl->border || yoffset + height > tl->height)) {
493 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
494 "glTexSubImage%uD(yoffset=%d + height=%d > %d)",
495 dims, yoffset, height, tl->height);
496 return GL_TRUE;
497 }
498 if (dims > 2 && (zoffset < -tl->border || zoffset + depth > tl->depth)) {
499 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
500 "glTexSubImage%uD(zoffset=%d and/or depth=%d)",
501 dims, zoffset, depth);
502 return GL_TRUE;
503 }
504
505 /* OK, no errors */
506 return GL_FALSE;
507}
508
509
510
511void STATE_APIENTRY
512crStateTexImage1D(GLenum target, GLint level, GLint internalFormat,
513 GLsizei width, GLint border, GLenum format,
514 GLenum type, const GLvoid * pixels)
515{
516 CRContext *g = GetCurrentContext();
517 CRTextureState *t = &(g->texture);
518 CRClientState *c = &(g->client);
519 CRTextureObj *tobj;
520 CRTextureLevel *tl;
521 CRStateBits *sb = GetCurrentBits();
522 CRTextureBits *tb = &(sb->texture);
523
524 FLUSH();
525
526 if (ErrorCheckTexImage(1, target, level, width, 1, 1, border)) {
527 if (IsProxyTarget(target)) {
528 /* clear all state, but don't generate error */
529 crStateTextureInitTextureObj(g, &(t->proxy1D), 0, GL_TEXTURE_1D);
530 }
531 else {
532 /* error was already recorded */
533 }
534 return;
535 }
536
537 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
538 CRASSERT(tobj);
539 CRASSERT(tl);
540
541 if (IsProxyTarget(target))
542 tl->bytes = 0;
543 else
544 tl->bytes = crImageSize(format, type, width, 1);
545
546#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
547 if (tl->bytes)
548 {
549 /* this is not a proxy texture target so alloc storage */
550 if (tl->img)
551 crFree(tl->img);
552 tl->img = (GLubyte *) crAlloc(tl->bytes);
553 if (!tl->img)
554 {
555 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
556 "glTexImage1D out of memory");
557 return;
558 }
559 if (pixels)
560 crPixelCopy1D((GLvoid *) tl->img, format, type,
561 pixels, format, type, width, &(c->unpack));
562 }
563#endif
564
565 tl->width = width;
566 tl->height = 1;
567 tl->depth = 1;
568 tl->format = format;
569 tl->border = border;
570 tl->internalFormat = internalFormat;
571 crStateTextureInitTextureFormat(tl, internalFormat);
572 tl->type = type;
573 tl->compressed = GL_FALSE;
574 if (width)
575 tl->bytesPerPixel = tl->bytes / width;
576 else
577 tl->bytesPerPixel = 0;
578
579#ifdef CR_SGIS_generate_mipmap
580 if (level == tobj->baseLevel && tobj->generateMipmap) {
581 generate_mipmap(tobj, target);
582 }
583 else {
584 tl->generateMipmap = GL_FALSE;
585 }
586#endif
587
588 /* XXX may need to do some fine-tuning here for proxy textures */
589 DIRTY(tobj->dirty, g->neg_bitid);
590 DIRTY(tobj->imageBit, g->neg_bitid);
591 DIRTY(tl->dirty, g->neg_bitid);
592 DIRTY(tb->dirty, g->neg_bitid);
593}
594
595
596void STATE_APIENTRY
597crStateTexImage2D(GLenum target, GLint level, GLint internalFormat,
598 GLsizei width, GLsizei height, GLint border,
599 GLenum format, GLenum type, const GLvoid * pixels)
600{
601 CRContext *g = GetCurrentContext();
602 CRTextureState *t = &(g->texture);
603 CRClientState *c = &(g->client);
604 CRTextureObj *tobj = NULL;
605 CRTextureLevel *tl = NULL;
606 CRStateBits *sb = GetCurrentBits();
607 CRTextureBits *tb = &(sb->texture);
608 const int is_distrib = ((type == GL_TRUE) || (type == GL_FALSE));
609
610 FLUSH();
611
612 /* NOTE: we skip parameter error checking if this is a distributed
613 * texture! The user better provide correct parameters!!!
614 */
615 if (!is_distrib
616 && ErrorCheckTexImage(2, target, level, width, height, 1, border)) {
617 if (IsProxyTarget(target)) {
618 /* clear all state, but don't generate error */
619 crStateTextureInitTextureObj(g, &(t->proxy2D), 0, GL_TEXTURE_2D);
620 }
621 else {
622 /* error was already recorded */
623 }
624 return;
625 }
626
627 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
628 CRASSERT(tobj);
629 CRASSERT(tl);
630
631 /* compute size of image buffer */
632 if (is_distrib) {
633 tl->bytes = crStrlen((char *) pixels) + 1;
634 tl->bytes += crImageSize(format, GL_UNSIGNED_BYTE, width, height);
635 }
636 else if (IsProxyTarget(target)) {
637 tl->bytes = 0;
638 }
639 else {
640 tl->bytes = crImageSize(format, type, width, height);
641 }
642
643#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
644 /* allocate the image buffer and fill it */
645 if (tl->bytes)
646 {
647 /* this is not a proxy texture target so alloc storage */
648 if (tl->img)
649 crFree(tl->img);
650 tl->img = (GLubyte *) crAlloc(tl->bytes);
651 if (!tl->img)
652 {
653 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
654 "glTexImage2D out of memory");
655 return;
656 }
657 if (pixels)
658 {
659 if (is_distrib)
660 {
661 crMemcpy((void *) tl->img, (void *) pixels, tl->bytes);
662 }
663 else
664 {
665 crPixelCopy2D(width, height,
666 (GLvoid *) tl->img, format, type, NULL, /* dst */
667 pixels, format, type, &(c->unpack)); /* src */
668 }
669 }
670 }
671#endif
672
673 tl->width = width;
674 tl->height = height;
675 tl->depth = 1;
676 tl->format = format;
677 tl->internalFormat = internalFormat;
678 crStateTextureInitTextureFormat(tl, internalFormat);
679 tl->border = border;
680 tl->type = type;
681 tl->compressed = GL_FALSE;
682 if (width && height)
683 {
684 if (is_distrib)
685 tl->bytesPerPixel = 3; /* only support GL_RGB */
686 else
687 tl->bytesPerPixel = tl->bytes / (width * height);
688 }
689 else
690 tl->bytesPerPixel = 0;
691
692#ifdef CR_SGIS_generate_mipmap
693 if (level == tobj->baseLevel && tobj->generateMipmap) {
694 generate_mipmap(tobj, target);
695 }
696 else {
697 tl->generateMipmap = GL_FALSE;
698 }
699#endif
700
701 /* XXX may need to do some fine-tuning here for proxy textures */
702 DIRTY(tobj->dirty, g->neg_bitid);
703 DIRTY(tobj->imageBit, g->neg_bitid);
704 DIRTY(tl->dirty, g->neg_bitid);
705 DIRTY(tb->dirty, g->neg_bitid);
706}
707
708
709#if defined( CR_OPENGL_VERSION_1_2 ) || defined( GL_EXT_texture3D )
710void STATE_APIENTRY
711crStateTexImage3D(GLenum target, GLint level,
712 GLint internalFormat,
713 GLsizei width, GLsizei height,
714 GLsizei depth, GLint border,
715 GLenum format, GLenum type, const GLvoid * pixels)
716{
717 CRContext *g = GetCurrentContext();
718 CRTextureState *t = &(g->texture);
719 CRClientState *c = &(g->client);
720 CRTextureObj *tobj = NULL;
721 CRTextureLevel *tl = NULL;
722 CRStateBits *sb = GetCurrentBits();
723 CRTextureBits *tb = &(sb->texture);
724
725 FLUSH();
726
727 if (ErrorCheckTexImage(3, target, level, width, height, depth, border)) {
728 if (IsProxyTarget(target)) {
729 /* clear all state, but don't generate error */
730 crStateTextureInitTextureObj(g, &(t->proxy3D), 0, GL_TEXTURE_3D);
731 }
732 else {
733 /* error was already recorded */
734 }
735 return;
736 }
737
738 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
739 CRASSERT(tobj);
740 CRASSERT(tl);
741
742 if (IsProxyTarget(target))
743 tl->bytes = 0;
744 else
745 tl->bytes = crTextureSize(format, type, width, height, depth);
746
747#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
748 if (tl->bytes)
749 {
750 /* this is not a proxy texture target so alloc storage */
751 if (tl->img)
752 crFree(tl->img);
753 tl->img = (GLubyte *) crAlloc(tl->bytes);
754 if (!tl->img)
755 {
756 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
757 "glTexImage3D out of memory");
758 return;
759 }
760 if (pixels)
761 crPixelCopy3D(width, height, depth, (GLvoid *) (tl->img), format, type,
762 NULL, pixels, format, type, &(c->unpack));
763 }
764#endif
765
766 tl->internalFormat = internalFormat;
767 tl->border = border;
768 tl->width = width;
769 tl->height = height;
770 tl->depth = depth;
771 tl->format = format;
772 tl->type = type;
773 tl->compressed = GL_FALSE;
774
775#ifdef CR_SGIS_generate_mipmap
776 if (level == tobj->baseLevel && tobj->generateMipmap) {
777 generate_mipmap(tobj, target);
778 }
779 else {
780 tl->generateMipmap = GL_FALSE;
781 }
782#endif
783
784 /* XXX may need to do some fine-tuning here for proxy textures */
785 DIRTY(tobj->dirty, g->neg_bitid);
786 DIRTY(tobj->imageBit, g->neg_bitid);
787 DIRTY(tl->dirty, g->neg_bitid);
788 DIRTY(tb->dirty, g->neg_bitid);
789}
790#endif /* CR_OPENGL_VERSION_1_2 || GL_EXT_texture3D */
791
792
793#ifdef GL_EXT_texture3D
794void STATE_APIENTRY
795crStateTexImage3DEXT(GLenum target, GLint level,
796 GLenum internalFormat,
797 GLsizei width, GLsizei height, GLsizei depth,
798 GLint border, GLenum format, GLenum type,
799 const GLvoid * pixels)
800{
801 crStateTexImage3D(target, level, (GLint) internalFormat, width, height,
802 depth, border, format, type, pixels);
803}
804#endif /* GL_EXT_texture3D */
805
806
807void STATE_APIENTRY
808crStateTexSubImage1D(GLenum target, GLint level, GLint xoffset,
809 GLsizei width, GLenum format,
810 GLenum type, const GLvoid * pixels)
811{
812 CRContext *g = GetCurrentContext();
813 CRTextureState *t = &(g->texture);
814 CRClientState *c = &(g->client);
815 CRStateBits *sb = GetCurrentBits();
816 CRTextureBits *tb = &(sb->texture);
817 CRTextureUnit *unit = t->unit + t->curTextureUnit;
818 CRTextureObj *tobj = unit->currentTexture1D;
819 CRTextureLevel *tl = tobj->level[0] + level;
820
821 FLUSH();
822
823 if (ErrorCheckTexSubImage(1, target, level, xoffset, 0, 0,
824 width, 1, 1)) {
825 return; /* GL error state already set */
826 }
827
828#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
829 xoffset += tl->border;
830
831 crPixelCopy1D((void *) (tl->img + xoffset * tl->bytesPerPixel),
832 tl->format, tl->type,
833 pixels, format, type, width, &(c->unpack));
834#endif
835
836#ifdef CR_SGIS_generate_mipmap
837 if (level == tobj->baseLevel && tobj->generateMipmap) {
838 generate_mipmap(tobj, target);
839 }
840 else {
841 tl->generateMipmap = GL_FALSE;
842 }
843#endif
844
845 DIRTY(tobj->dirty, g->neg_bitid);
846 DIRTY(tobj->imageBit, g->neg_bitid);
847 DIRTY(tl->dirty, g->neg_bitid);
848 DIRTY(tb->dirty, g->neg_bitid);
849}
850
851
852void STATE_APIENTRY
853crStateTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
854 GLsizei width, GLsizei height,
855 GLenum format, GLenum type, const GLvoid * pixels)
856{
857 CRContext *g = GetCurrentContext();
858 CRClientState *c = &(g->client);
859 CRStateBits *sb = GetCurrentBits();
860 CRTextureBits *tb = &(sb->texture);
861 CRTextureObj *tobj;
862 CRTextureLevel *tl;
863 GLubyte *subimg = NULL;
864 GLubyte *img = NULL;
865#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
866 GLubyte *src;
867 int i;
868#endif
869
870 FLUSH();
871
872 if (ErrorCheckTexSubImage(2, target, level, xoffset, yoffset, 0,
873 width, height, 1)) {
874 return; /* GL error state already set */
875 }
876
877 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
878 CRASSERT(tobj);
879 CRASSERT(tl);
880
881#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
882 xoffset += tl->border;
883 yoffset += tl->border;
884
885 subimg = (GLubyte *) crAlloc(crImageSize(tl->format, tl->type, width, height));
886
887 crPixelCopy2D(width, height, subimg, tl->format, tl->type, NULL, /* dst */
888 pixels, format, type, &(c->unpack)); /* src */
889
890 img = tl->img +
891 xoffset * tl->bytesPerPixel + yoffset * tl->width * tl->bytesPerPixel;
892
893 src = subimg;
894
895 /* Copy the data into the texture */
896 for (i = 0; i < height; i++)
897 {
898 crMemcpy(img, src, tl->bytesPerPixel * width);
899 img += tl->width * tl->bytesPerPixel;
900 src += width * tl->bytesPerPixel;
901 }
902
903 crFree(subimg);
904#endif
905
906#ifdef CR_SGIS_generate_mipmap
907 if (level == tobj->baseLevel && tobj->generateMipmap) {
908 generate_mipmap(tobj, target);
909 }
910 else {
911 tl->generateMipmap = GL_FALSE;
912 }
913#endif
914
915 DIRTY(tobj->dirty, g->neg_bitid);
916 DIRTY(tobj->imageBit, g->neg_bitid);
917 DIRTY(tl->dirty, g->neg_bitid);
918 DIRTY(tb->dirty, g->neg_bitid);
919}
920
921#if defined( CR_OPENGL_VERSION_1_2 )
922void STATE_APIENTRY
923crStateTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
924 GLint zoffset, GLsizei width, GLsizei height,
925 GLsizei depth, GLenum format, GLenum type,
926 const GLvoid * pixels)
927{
928 CRContext *g = GetCurrentContext();
929 CRTextureState *t = &(g->texture);
930 CRClientState *c = &(g->client);
931 CRStateBits *sb = GetCurrentBits();
932 CRTextureBits *tb = &(sb->texture);
933 CRTextureUnit *unit = t->unit + t->curTextureUnit;
934 CRTextureObj *tobj = unit->currentTexture3D;
935 CRTextureLevel *tl = tobj->level[0] + level;
936 GLubyte *subimg = NULL;
937 GLubyte *img = NULL;
938#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
939 GLubyte *src;
940 int i;
941#endif
942
943 FLUSH();
944
945 if (ErrorCheckTexSubImage(3, target, level, xoffset, yoffset, zoffset,
946 width, height, depth)) {
947 return; /* GL error state already set */
948 }
949
950#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
951 xoffset += tl->border;
952 yoffset += tl->border;
953 zoffset += tl->border;
954
955 subimg =
956 (GLubyte *)
957 crAlloc(crTextureSize(tl->format, tl->type, width, height, depth));
958
959 crPixelCopy3D(width, height, depth, subimg, tl->format, tl->type, NULL,
960 pixels, format, type, &(c->unpack));
961
962 img = tl->img + xoffset * tl->bytesPerPixel +
963 yoffset * tl->width * tl->bytesPerPixel +
964 zoffset * tl->width * tl->height * tl->bytesPerPixel;
965
966 src = subimg;
967
968 /* Copy the data into the texture */
969 for (i = 0; i < depth; i++)
970 {
971 crMemcpy(img, src, tl->bytesPerPixel * width * height);
972 img += tl->width * tl->height * tl->bytesPerPixel;
973 src += width * height * tl->bytesPerPixel;
974 }
975
976 crFree(subimg);
977#endif
978
979#ifdef CR_SGIS_generate_mipmap
980 if (level == tobj->baseLevel && tobj->generateMipmap) {
981 generate_mipmap(tobj, target);
982 }
983 else {
984 tl->generateMipmap = GL_FALSE;
985 }
986#endif
987
988 DIRTY(tobj->dirty, g->neg_bitid);
989 DIRTY(tobj->imageBit, g->neg_bitid);
990 DIRTY(tl->dirty, g->neg_bitid);
991 DIRTY(tb->dirty, g->neg_bitid);
992}
993#endif /* CR_OPENGL_VERSION_1_2 || GL_EXT_texture3D */
994
995
996void STATE_APIENTRY
997crStateCompressedTexImage1DARB(GLenum target, GLint level,
998 GLenum internalFormat, GLsizei width,
999 GLint border, GLsizei imageSize,
1000 const GLvoid * data)
1001{
1002 CRContext *g = GetCurrentContext();
1003 CRTextureState *t = &(g->texture);
1004 CRTextureObj *tobj;
1005 CRTextureLevel *tl;
1006 CRStateBits *sb = GetCurrentBits();
1007 CRTextureBits *tb = &(sb->texture);
1008
1009 FLUSH();
1010
1011 if (ErrorCheckTexImage(1, target, level, width, 1, 1, border)) {
1012 if (IsProxyTarget(target)) {
1013 /* clear all state, but don't generate error */
1014 crStateTextureInitTextureObj(g, &(t->proxy1D), 0, GL_TEXTURE_1D);
1015 }
1016 else {
1017 /* error was already recorded */
1018 }
1019 return;
1020 }
1021
1022 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1023 CRASSERT(tobj);
1024 CRASSERT(tl);
1025
1026 if (IsProxyTarget(target))
1027 tl->bytes = 0;
1028 else
1029 tl->bytes = imageSize;
1030
1031#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
1032 if (tl->bytes)
1033 {
1034 /* this is not a proxy texture target so alloc storage */
1035 if (tl->img)
1036 crFree(tl->img);
1037 tl->img = (GLubyte *) crAlloc(tl->bytes);
1038 if (!tl->img)
1039 {
1040 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
1041 "glTexImage1D out of memory");
1042 return;
1043 }
1044 if (data)
1045 crMemcpy(tl->img, data, imageSize);
1046 }
1047#endif
1048
1049 tl->width = width;
1050 tl->height = 1;
1051 tl->depth = 1;
1052 tl->border = border;
1053 tl->format = GL_NONE;
1054 tl->type = GL_NONE;
1055 tl->internalFormat = internalFormat;
1056 crStateTextureInitTextureFormat(tl, internalFormat);
1057 tl->compressed = GL_TRUE;
1058 tl->bytesPerPixel = 0; /* n/a */
1059
1060#ifdef CR_SGIS_generate_mipmap
1061 if (level == tobj->baseLevel && tobj->generateMipmap) {
1062 generate_mipmap(tobj, target);
1063 }
1064 else {
1065 tl->generateMipmap = GL_FALSE;
1066 }
1067#endif
1068
1069 DIRTY(tobj->dirty, g->neg_bitid);
1070 DIRTY(tobj->imageBit, g->neg_bitid);
1071 DIRTY(tl->dirty, g->neg_bitid);
1072 DIRTY(tb->dirty, g->neg_bitid);
1073}
1074
1075
1076void STATE_APIENTRY
1077crStateCompressedTexImage2DARB(GLenum target, GLint level,
1078 GLenum internalFormat, GLsizei width,
1079 GLsizei height, GLint border,
1080 GLsizei imageSize, const GLvoid * data)
1081{
1082 CRContext *g = GetCurrentContext();
1083 CRTextureState *t = &(g->texture);
1084 CRTextureObj *tobj = NULL;
1085 CRTextureLevel *tl = NULL;
1086 CRStateBits *sb = GetCurrentBits();
1087 CRTextureBits *tb = &(sb->texture);
1088
1089 FLUSH();
1090
1091 if (ErrorCheckTexImage(2, target, level, width, height, 1, border)) {
1092 if (IsProxyTarget(target)) {
1093 /* clear all state, but don't generate error */
1094 crStateTextureInitTextureObj(g, &(t->proxy2D), 0, GL_TEXTURE_2D);
1095 }
1096 else {
1097 /* error was already recorded */
1098 }
1099 return;
1100 }
1101
1102 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1103 CRASSERT(tobj);
1104 CRASSERT(tl);
1105
1106 if (IsProxyTarget(target))
1107 tl->bytes = 0;
1108 else
1109 tl->bytes = imageSize;
1110
1111#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
1112 if (tl->bytes)
1113 {
1114 /* this is not a proxy texture target so alloc storage */
1115 if (tl->img)
1116 crFree(tl->img);
1117 tl->img = (GLubyte *) crAlloc(tl->bytes);
1118 if (!tl->img)
1119 {
1120 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
1121 "glTexImage2D out of memory");
1122 return;
1123 }
1124 if (data)
1125 crMemcpy(tl->img, data, imageSize);
1126 }
1127#endif
1128
1129 tl->width = width;
1130 tl->height = height;
1131 tl->depth = 1;
1132 tl->border = border;
1133 tl->format = GL_NONE;
1134 tl->type = GL_NONE;
1135 tl->internalFormat = internalFormat;
1136 crStateTextureInitTextureFormat(tl, internalFormat);
1137 tl->compressed = GL_TRUE;
1138 tl->bytesPerPixel = 0; /* n/a */
1139
1140#ifdef CR_SGIS_generate_mipmap
1141 if (level == tobj->baseLevel && tobj->generateMipmap) {
1142 generate_mipmap(tobj, target);
1143 }
1144 else {
1145 tl->generateMipmap = GL_FALSE;
1146 }
1147#endif
1148
1149 /* XXX may need to do some fine-tuning here for proxy textures */
1150 DIRTY(tobj->dirty, g->neg_bitid);
1151 DIRTY(tobj->imageBit, g->neg_bitid);
1152 DIRTY(tl->dirty, g->neg_bitid);
1153 DIRTY(tb->dirty, g->neg_bitid);
1154}
1155
1156
1157void STATE_APIENTRY
1158crStateCompressedTexImage3DARB(GLenum target, GLint level,
1159 GLenum internalFormat, GLsizei width,
1160 GLsizei height, GLsizei depth, GLint border,
1161 GLsizei imageSize, const GLvoid * data)
1162{
1163 CRContext *g = GetCurrentContext();
1164 CRTextureState *t = &(g->texture);
1165 CRTextureObj *tobj = NULL;
1166 CRTextureLevel *tl = NULL;
1167 CRStateBits *sb = GetCurrentBits();
1168 CRTextureBits *tb = &(sb->texture);
1169
1170 FLUSH();
1171
1172 if (ErrorCheckTexImage(3, target, level, width, height, depth, border)) {
1173 if (IsProxyTarget(target)) {
1174 /* clear all state, but don't generate error */
1175 crStateTextureInitTextureObj(g, &(t->proxy3D), 0, GL_TEXTURE_3D);
1176 }
1177 else {
1178 /* error was already recorded */
1179 }
1180 return;
1181 }
1182
1183 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1184 CRASSERT(tobj);
1185 CRASSERT(tl);
1186
1187 if (IsProxyTarget(target))
1188 tl->bytes = 0;
1189 else
1190 tl->bytes = imageSize;
1191
1192#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
1193 if (tl->bytes)
1194 {
1195 /* this is not a proxy texture target so alloc storage */
1196 if (tl->img)
1197 crFree(tl->img);
1198 tl->img = (GLubyte *) crAlloc(tl->bytes);
1199 if (!tl->img)
1200 {
1201 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
1202 "glCompressedTexImage3D out of memory");
1203 return;
1204 }
1205 if (data)
1206 crMemcpy(tl->img, data, imageSize);
1207 }
1208#endif
1209
1210 tl->width = width;
1211 tl->height = height;
1212 tl->depth = depth;
1213 tl->border = border;
1214 tl->format = GL_NONE;
1215 tl->type = GL_NONE;
1216 tl->internalFormat = internalFormat;
1217 crStateTextureInitTextureFormat(tl, internalFormat);
1218 tl->compressed = GL_TRUE;
1219 tl->bytesPerPixel = 0; /* n/a */
1220
1221#ifdef CR_SGIS_generate_mipmap
1222 if (level == tobj->baseLevel && tobj->generateMipmap) {
1223 generate_mipmap(tobj, target);
1224 }
1225 else {
1226 tl->generateMipmap = GL_FALSE;
1227 }
1228#endif
1229
1230 /* XXX may need to do some fine-tuning here for proxy textures */
1231 DIRTY(tobj->dirty, g->neg_bitid);
1232 DIRTY(tobj->imageBit, g->neg_bitid);
1233 DIRTY(tl->dirty, g->neg_bitid);
1234 DIRTY(tb->dirty, g->neg_bitid);
1235}
1236
1237
1238void STATE_APIENTRY
1239crStateCompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
1240 GLsizei width, GLenum format,
1241 GLsizei imageSize, const GLvoid * data)
1242{
1243 CRContext *g = GetCurrentContext();
1244 CRTextureState *t = &(g->texture);
1245 CRStateBits *sb = GetCurrentBits();
1246 CRTextureBits *tb = &(sb->texture);
1247 CRTextureUnit *unit = t->unit + t->curTextureUnit;
1248 CRTextureObj *tobj = unit->currentTexture1D;
1249 CRTextureLevel *tl = tobj->level[0] + level;
1250
1251 FLUSH();
1252
1253 if (ErrorCheckTexSubImage(1, target, level, xoffset, 0, 0, width, 1, 1)) {
1254 return; /* GL error state already set */
1255 }
1256
1257#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
1258 xoffset += tl->border;
1259
1260 if (xoffset == 0 && width == tl->width) {
1261 /* just memcpy */
1262 crMemcpy(tl->img, data, imageSize);
1263 }
1264 else {
1265 /* XXX this depends on the exact compression method */
1266 crWarning("Not implemented part crStateCompressedTexSubImage1DARB");
1267 }
1268#endif
1269
1270#ifdef CR_SGIS_generate_mipmap
1271 if (level == tobj->baseLevel && tobj->generateMipmap) {
1272 generate_mipmap(tobj, target);
1273 }
1274 else {
1275 tl->generateMipmap = GL_FALSE;
1276 }
1277#endif
1278
1279 DIRTY(tobj->dirty, g->neg_bitid);
1280 DIRTY(tobj->imageBit, g->neg_bitid);
1281 DIRTY(tl->dirty, g->neg_bitid);
1282 DIRTY(tb->dirty, g->neg_bitid);
1283}
1284
1285
1286void STATE_APIENTRY
1287crStateCompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
1288 GLint yoffset, GLsizei width,
1289 GLsizei height, GLenum format,
1290 GLsizei imageSize, const GLvoid * data)
1291{
1292 CRContext *g = GetCurrentContext();
1293 CRTextureState *t = &(g->texture);
1294 CRStateBits *sb = GetCurrentBits();
1295 CRTextureBits *tb = &(sb->texture);
1296 CRTextureUnit *unit = t->unit + t->curTextureUnit;
1297 CRTextureObj *tobj = unit->currentTexture1D;
1298 CRTextureLevel *tl = tobj->level[0] + level;
1299
1300 FLUSH();
1301
1302 if (ErrorCheckTexSubImage(2, target, level, xoffset, yoffset, 0,
1303 width, height, 1)) {
1304 return; /* GL error state already set */
1305 }
1306
1307#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
1308 xoffset += tl->border;
1309 yoffset += tl->border;
1310
1311 if (xoffset == 0 && width == tl->width
1312 && yoffset == 0 && height == tl->height)
1313 {
1314 /* just memcpy */
1315 crMemcpy(tl->img, data, imageSize);
1316 }
1317 else {
1318 /* XXX this depends on the exact compression method */
1319 crWarning("Not implemented part crStateCompressedTexSubImage2DARB");
1320 }
1321#endif
1322
1323#ifdef CR_SGIS_generate_mipmap
1324 if (level == tobj->baseLevel && tobj->generateMipmap) {
1325 generate_mipmap(tobj, target);
1326 }
1327 else {
1328 tl->generateMipmap = GL_FALSE;
1329 }
1330#endif
1331
1332 DIRTY(tobj->dirty, g->neg_bitid);
1333 DIRTY(tobj->imageBit, g->neg_bitid);
1334 DIRTY(tl->dirty, g->neg_bitid);
1335 DIRTY(tb->dirty, g->neg_bitid);
1336}
1337
1338
1339void STATE_APIENTRY
1340crStateCompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
1341 GLint yoffset, GLint zoffset, GLsizei width,
1342 GLsizei height, GLsizei depth,
1343 GLenum format, GLsizei imageSize,
1344 const GLvoid * data)
1345{
1346 CRContext *g = GetCurrentContext();
1347 CRTextureState *t = &(g->texture);
1348 CRStateBits *sb = GetCurrentBits();
1349 CRTextureBits *tb = &(sb->texture);
1350 CRTextureUnit *unit = t->unit + t->curTextureUnit;
1351 CRTextureObj *tobj = unit->currentTexture1D;
1352 CRTextureLevel *tl = tobj->level[0] + level;
1353
1354 FLUSH();
1355
1356 if (ErrorCheckTexSubImage(3, target, level, xoffset, yoffset, zoffset,
1357 width, height, depth)) {
1358 return; /* GL error state already set */
1359 }
1360
1361#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
1362 xoffset += tl->border;
1363 yoffset += tl->border;
1364 zoffset += tl->border;
1365
1366 if (xoffset == 0 && width == tl->width &&
1367 yoffset == 0 && height == tl->height &&
1368 zoffset == 0 && depth == tl->depth) {
1369 /* just memcpy */
1370 crMemcpy(tl->img, data, imageSize);
1371 }
1372 else {
1373 /* XXX this depends on the exact compression method */
1374 crWarning("Not implemented part crStateCompressedTexSubImage3DARB");
1375 }
1376#endif
1377
1378#ifdef CR_SGIS_generate_mipmap
1379 if (level == tobj->baseLevel && tobj->generateMipmap) {
1380 generate_mipmap(tobj, target);
1381 }
1382 else {
1383 tl->generateMipmap = GL_FALSE;
1384 }
1385#endif
1386
1387 DIRTY(tobj->dirty, g->neg_bitid);
1388 DIRTY(tobj->imageBit, g->neg_bitid);
1389 DIRTY(tl->dirty, g->neg_bitid);
1390 DIRTY(tb->dirty, g->neg_bitid);
1391}
1392
1393
1394void STATE_APIENTRY
1395crStateGetCompressedTexImageARB(GLenum target, GLint level, GLvoid * img)
1396{
1397 CRContext *g = GetCurrentContext();
1398 CRTextureObj *tobj;
1399 CRTextureLevel *tl;
1400
1401 if (g->current.inBeginEnd)
1402 {
1403 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1404 "glGetCompressedTexImage called in begin/end");
1405 return;
1406 }
1407
1408 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1409 if (!tobj || !tl) {
1410 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1411 "glGetCompressedTexImage(invalid target or level)");
1412 return;
1413 }
1414
1415 if (!tl->compressed) {
1416 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1417 "glGetCompressedTexImage(not a compressed texture)");
1418 return;
1419 }
1420
1421#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
1422 crMemcpy(img, tl->img, tl->bytes);
1423#else
1424 diff_api.GetCompressedTexImageARB(target, level, img);
1425#endif
1426}
1427
1428
1429void STATE_APIENTRY
1430crStateGetTexImage(GLenum target, GLint level, GLenum format,
1431 GLenum type, GLvoid * pixels)
1432{
1433 CRContext *g = GetCurrentContext();
1434 CRClientState *c = &(g->client);
1435 CRTextureObj *tobj;
1436 CRTextureLevel *tl;
1437
1438 if (g->current.inBeginEnd)
1439 {
1440 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1441 "glGetTexImage called in begin/end");
1442 return;
1443 }
1444
1445 crStateGetTextureObjectAndImage(g, target, level, &tobj, &tl);
1446 if (!tobj || !tl) {
1447 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1448 "glGetTexImage(invalid target or level)");
1449 return;
1450 }
1451
1452 if (tl->compressed) {
1453 crWarning("glGetTexImage cannot decompress a compressed texture!");
1454 return;
1455 }
1456
1457 switch (format)
1458 {
1459 case GL_RED:
1460 case GL_GREEN:
1461 case GL_BLUE:
1462 case GL_ALPHA:
1463 case GL_RGB:
1464 case GL_RGBA:
1465 case GL_LUMINANCE:
1466 case GL_LUMINANCE_ALPHA:
1467 break;
1468 default:
1469 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1470 "glGetTexImage called with bogus format: %d", format);
1471 return;
1472 }
1473
1474 switch (type)
1475 {
1476 case GL_UNSIGNED_BYTE:
1477 case GL_BYTE:
1478 case GL_UNSIGNED_SHORT:
1479 case GL_SHORT:
1480 case GL_UNSIGNED_INT:
1481 case GL_INT:
1482 case GL_FLOAT:
1483 break;
1484 default:
1485 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1486 "glGetTexImage called with bogus type: %d", type);
1487 return;
1488 }
1489
1490#ifndef CR_STATE_NO_TEXTURE_IMAGE_STORE
1491#ifdef CR_OPENGL_VERSION_1_2
1492 if (target == GL_TEXTURE_3D)
1493 {
1494 crPixelCopy3D(tl->width, tl->height, tl->depth, (GLvoid *) pixels, format,
1495 type, NULL, (tl->img), format, type, &(c->pack));
1496 }
1497 else
1498#endif
1499 if ((target == GL_TEXTURE_1D) || (target == GL_TEXTURE_2D))
1500 {
1501 crPixelCopy2D(tl->width, tl->height, (GLvoid *) pixels, format, type, NULL, /* dst */
1502 tl->img, format, type, &(c->pack)); /* src */
1503 }
1504#else
1505 diff_api.GetTexImage(target, level, format, type, pixels);
1506#endif
1507}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette