[MESA]
[reactos.git] / reactos / dll / opengl / mesa / src / mesa / main / teximage.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file teximage.c
28 * Texture image-related functions.
29 */
30
31
32 #include "glheader.h"
33 #include "bufferobj.h"
34 #include "context.h"
35 #include "enums.h"
36 #include "framebuffer.h"
37 #include "hash.h"
38 #include "image.h"
39 #include "imports.h"
40 #include "macros.h"
41 #include "mfeatures.h"
42 #include "state.h"
43 #include "teximage.h"
44 #include "texstate.h"
45 #include "texpal.h"
46 #include "mtypes.h"
47
48
49 /**
50 * State changes which we care about for glCopyTex[Sub]Image() calls.
51 * In particular, we care about pixel transfer state and buffer state
52 * (such as glReadBuffer to make sure we read from the right renderbuffer).
53 */
54 #define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL)
55
56
57
58 /**
59 * Return the simple base format for a given internal texture format.
60 * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
61 *
62 * \param ctx GL context.
63 * \param internalFormat the internal texture format token or 1, 2, 3, or 4.
64 *
65 * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
66 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
67 *
68 * This is the format which is used during texture application (i.e. the
69 * texture format and env mode determine the arithmetic used.
70 *
71 * XXX this could be static
72 */
73 GLint
74 _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
75 {
76 switch (internalFormat) {
77 case GL_ALPHA:
78 case GL_ALPHA4:
79 case GL_ALPHA8:
80 case GL_ALPHA12:
81 case GL_ALPHA16:
82 return GL_ALPHA;
83 case 1:
84 case GL_LUMINANCE:
85 case GL_LUMINANCE4:
86 case GL_LUMINANCE8:
87 case GL_LUMINANCE12:
88 case GL_LUMINANCE16:
89 return GL_LUMINANCE;
90 case 2:
91 case GL_LUMINANCE_ALPHA:
92 case GL_LUMINANCE4_ALPHA4:
93 case GL_LUMINANCE6_ALPHA2:
94 case GL_LUMINANCE8_ALPHA8:
95 case GL_LUMINANCE12_ALPHA4:
96 case GL_LUMINANCE12_ALPHA12:
97 case GL_LUMINANCE16_ALPHA16:
98 return GL_LUMINANCE_ALPHA;
99 case GL_INTENSITY:
100 case GL_INTENSITY4:
101 case GL_INTENSITY8:
102 case GL_INTENSITY12:
103 case GL_INTENSITY16:
104 return GL_INTENSITY;
105 case 3:
106 case GL_RGB:
107 case GL_R3_G3_B2:
108 case GL_RGB4:
109 case GL_RGB5:
110 case GL_RGB8:
111 case GL_RGB10:
112 case GL_RGB12:
113 case GL_RGB16:
114 return GL_RGB;
115 case 4:
116 case GL_RGBA:
117 case GL_RGBA2:
118 case GL_RGBA4:
119 case GL_RGB5_A1:
120 case GL_RGBA8:
121 case GL_RGB10_A2:
122 case GL_RGBA12:
123 case GL_RGBA16:
124 return GL_RGBA;
125 default:
126 ; /* fallthrough */
127 }
128
129 if (ctx->Extensions.MESA_ycbcr_texture) {
130 if (internalFormat == GL_YCBCR_MESA)
131 return GL_YCBCR_MESA;
132 }
133
134 if (ctx->Extensions.ARB_texture_float) {
135 switch (internalFormat) {
136 case GL_ALPHA16F_ARB:
137 case GL_ALPHA32F_ARB:
138 return GL_ALPHA;
139 case GL_RGBA16F_ARB:
140 case GL_RGBA32F_ARB:
141 return GL_RGBA;
142 case GL_RGB16F_ARB:
143 case GL_RGB32F_ARB:
144 return GL_RGB;
145 case GL_INTENSITY16F_ARB:
146 case GL_INTENSITY32F_ARB:
147 return GL_INTENSITY;
148 case GL_LUMINANCE16F_ARB:
149 case GL_LUMINANCE32F_ARB:
150 return GL_LUMINANCE;
151 case GL_LUMINANCE_ALPHA16F_ARB:
152 case GL_LUMINANCE_ALPHA32F_ARB:
153 return GL_LUMINANCE_ALPHA;
154 default:
155 ; /* fallthrough */
156 }
157 }
158
159 if (ctx->Extensions.ATI_envmap_bumpmap) {
160 switch (internalFormat) {
161 case GL_DUDV_ATI:
162 case GL_DU8DV8_ATI:
163 return GL_DUDV_ATI;
164 default:
165 ; /* fallthrough */
166 }
167 }
168
169 if (ctx->VersionMajor >= 3 ||
170 ctx->Extensions.EXT_texture_integer) {
171 switch (internalFormat) {
172 case GL_RGBA8UI_EXT:
173 case GL_RGBA16UI_EXT:
174 case GL_RGBA32UI_EXT:
175 case GL_RGBA8I_EXT:
176 case GL_RGBA16I_EXT:
177 case GL_RGBA32I_EXT:
178 case GL_RGB10_A2UI:
179 return GL_RGBA;
180 case GL_RGB8UI_EXT:
181 case GL_RGB16UI_EXT:
182 case GL_RGB32UI_EXT:
183 case GL_RGB8I_EXT:
184 case GL_RGB16I_EXT:
185 case GL_RGB32I_EXT:
186 return GL_RGB;
187 }
188 }
189
190 if (ctx->Extensions.EXT_texture_integer) {
191 switch (internalFormat) {
192 case GL_ALPHA8UI_EXT:
193 case GL_ALPHA16UI_EXT:
194 case GL_ALPHA32UI_EXT:
195 case GL_ALPHA8I_EXT:
196 case GL_ALPHA16I_EXT:
197 case GL_ALPHA32I_EXT:
198 return GL_ALPHA;
199 case GL_INTENSITY8UI_EXT:
200 case GL_INTENSITY16UI_EXT:
201 case GL_INTENSITY32UI_EXT:
202 case GL_INTENSITY8I_EXT:
203 case GL_INTENSITY16I_EXT:
204 case GL_INTENSITY32I_EXT:
205 return GL_INTENSITY;
206 case GL_LUMINANCE8UI_EXT:
207 case GL_LUMINANCE16UI_EXT:
208 case GL_LUMINANCE32UI_EXT:
209 case GL_LUMINANCE8I_EXT:
210 case GL_LUMINANCE16I_EXT:
211 case GL_LUMINANCE32I_EXT:
212 return GL_LUMINANCE;
213 case GL_LUMINANCE_ALPHA8UI_EXT:
214 case GL_LUMINANCE_ALPHA16UI_EXT:
215 case GL_LUMINANCE_ALPHA32UI_EXT:
216 case GL_LUMINANCE_ALPHA8I_EXT:
217 case GL_LUMINANCE_ALPHA16I_EXT:
218 case GL_LUMINANCE_ALPHA32I_EXT:
219 return GL_LUMINANCE_ALPHA;
220 default:
221 ; /* fallthrough */
222 }
223 }
224
225 return -1; /* error */
226 }
227
228
229 /**
230 * Is the given texture format a generic compressed format?
231 */
232
233
234 /**
235 * For cube map faces, return a face index in [0,5].
236 * For other targets return 0;
237 */
238 GLuint
239 _mesa_tex_target_to_face(GLenum target)
240 {
241 if (_mesa_is_cube_face(target))
242 return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
243 else
244 return 0;
245 }
246
247
248
249 /**
250 * Install gl_texture_image in a gl_texture_object according to the target
251 * and level parameters.
252 *
253 * \param tObj texture object.
254 * \param target texture target.
255 * \param level image level.
256 * \param texImage texture image.
257 */
258 static void
259 set_tex_image(struct gl_texture_object *tObj,
260 GLenum target, GLint level,
261 struct gl_texture_image *texImage)
262 {
263 const GLuint face = _mesa_tex_target_to_face(target);
264
265 ASSERT(tObj);
266 ASSERT(texImage);
267
268 tObj->Image[face][level] = texImage;
269
270 /* Set the 'back' pointer */
271 texImage->TexObject = tObj;
272 texImage->Level = level;
273 texImage->Face = face;
274 }
275
276
277 /**
278 * Allocate a texture image structure.
279 *
280 * Called via ctx->Driver.NewTextureImage() unless overriden by a device
281 * driver.
282 *
283 * \return a pointer to gl_texture_image struct with all fields initialized to
284 * zero.
285 */
286 struct gl_texture_image *
287 _mesa_new_texture_image( struct gl_context *ctx )
288 {
289 (void) ctx;
290 return CALLOC_STRUCT(gl_texture_image);
291 }
292
293
294 /**
295 * Free a gl_texture_image and associated data.
296 * This function is a fallback called via ctx->Driver.DeleteTextureImage().
297 *
298 * \param texImage texture image.
299 *
300 * Free the texture image structure and the associated image data.
301 */
302 void
303 _mesa_delete_texture_image(struct gl_context *ctx,
304 struct gl_texture_image *texImage)
305 {
306 /* Free texImage->Data and/or any other driver-specific texture
307 * image storage.
308 */
309 ASSERT(ctx->Driver.FreeTextureImageBuffer);
310 ctx->Driver.FreeTextureImageBuffer( ctx, texImage );
311 free(texImage);
312 }
313
314
315 /**
316 * Test if a target is a proxy target.
317 *
318 * \param target texture target.
319 *
320 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
321 */
322 GLboolean
323 _mesa_is_proxy_texture(GLenum target)
324 {
325 /*
326 * NUM_TEXTURE_TARGETS should match number of terms below, except there's no
327 * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
328 */
329 assert(NUM_TEXTURE_TARGETS == 7 + 2);
330
331 return (target == GL_PROXY_TEXTURE_1D ||
332 target == GL_PROXY_TEXTURE_2D ||
333 target == GL_PROXY_TEXTURE_3D ||
334 target == GL_PROXY_TEXTURE_CUBE_MAP_ARB);
335 }
336
337
338 /**
339 * Return the proxy target which corresponds to the given texture target
340 */
341 static GLenum
342 get_proxy_target(GLenum target)
343 {
344 switch (target) {
345 case GL_TEXTURE_1D:
346 case GL_PROXY_TEXTURE_1D:
347 return GL_PROXY_TEXTURE_1D;
348 case GL_TEXTURE_2D:
349 case GL_PROXY_TEXTURE_2D:
350 return GL_PROXY_TEXTURE_2D;
351 case GL_TEXTURE_3D:
352 case GL_PROXY_TEXTURE_3D:
353 return GL_PROXY_TEXTURE_3D;
354 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
355 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
356 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
357 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
358 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
359 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
360 case GL_TEXTURE_CUBE_MAP_ARB:
361 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
362 return GL_PROXY_TEXTURE_CUBE_MAP_ARB;
363 default:
364 _mesa_problem(NULL, "unexpected target in get_proxy_target()");
365 return 0;
366 }
367 }
368
369
370 /**
371 * Get the texture object that corresponds to the target of the given
372 * texture unit. The target should have already been checked for validity.
373 *
374 * \param ctx GL context.
375 * \param texUnit texture unit.
376 * \param target texture target.
377 *
378 * \return pointer to the texture object on success, or NULL on failure.
379 */
380 struct gl_texture_object *
381 _mesa_select_tex_object(struct gl_context *ctx,
382 const struct gl_texture_unit *texUnit,
383 GLenum target)
384 {
385 switch (target) {
386 case GL_TEXTURE_1D:
387 return texUnit->CurrentTex[TEXTURE_1D_INDEX];
388 case GL_PROXY_TEXTURE_1D:
389 return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
390 case GL_TEXTURE_2D:
391 return texUnit->CurrentTex[TEXTURE_2D_INDEX];
392 case GL_PROXY_TEXTURE_2D:
393 return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
394 case GL_TEXTURE_3D:
395 return texUnit->CurrentTex[TEXTURE_3D_INDEX];
396 case GL_PROXY_TEXTURE_3D:
397 return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
398 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
399 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
400 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
401 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
402 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
403 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
404 case GL_TEXTURE_CUBE_MAP_ARB:
405 return ctx->Extensions.ARB_texture_cube_map
406 ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL;
407 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
408 return ctx->Extensions.ARB_texture_cube_map
409 ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
410 default:
411 _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
412 return NULL;
413 }
414 }
415
416
417 /**
418 * Return pointer to texture object for given target on current texture unit.
419 */
420 struct gl_texture_object *
421 _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target)
422 {
423 struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
424 return _mesa_select_tex_object(ctx, texUnit, target);
425 }
426
427
428 /**
429 * Get a texture image pointer from a texture object, given a texture
430 * target and mipmap level. The target and level parameters should
431 * have already been error-checked.
432 *
433 * \param ctx GL context.
434 * \param texObj texture unit.
435 * \param target texture target.
436 * \param level image level.
437 *
438 * \return pointer to the texture image structure, or NULL on failure.
439 */
440 struct gl_texture_image *
441 _mesa_select_tex_image(struct gl_context *ctx,
442 const struct gl_texture_object *texObj,
443 GLenum target, GLint level)
444 {
445 const GLuint face = _mesa_tex_target_to_face(target);
446
447 ASSERT(texObj);
448 ASSERT(level >= 0);
449 ASSERT(level < MAX_TEXTURE_LEVELS);
450
451 return texObj->Image[face][level];
452 }
453
454
455 /**
456 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
457 * it and install it. Only return NULL if passed a bad parameter or run
458 * out of memory.
459 */
460 struct gl_texture_image *
461 _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
462 GLenum target, GLint level)
463 {
464 struct gl_texture_image *texImage;
465
466 if (!texObj)
467 return NULL;
468
469 texImage = _mesa_select_tex_image(ctx, texObj, target, level);
470 if (!texImage) {
471 texImage = ctx->Driver.NewTextureImage(ctx);
472 if (!texImage) {
473 _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
474 return NULL;
475 }
476
477 set_tex_image(texObj, target, level, texImage);
478 }
479
480 return texImage;
481 }
482
483
484 /**
485 * Return pointer to the specified proxy texture image.
486 * Note that proxy textures are per-context, not per-texture unit.
487 * \return pointer to texture image or NULL if invalid target, invalid
488 * level, or out of memory.
489 */
490 struct gl_texture_image *
491 _mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
492 {
493 struct gl_texture_image *texImage;
494 GLuint texIndex;
495
496 if (level < 0 )
497 return NULL;
498
499 switch (target) {
500 case GL_PROXY_TEXTURE_1D:
501 if (level >= ctx->Const.MaxTextureLevels)
502 return NULL;
503 texIndex = TEXTURE_1D_INDEX;
504 break;
505 case GL_PROXY_TEXTURE_2D:
506 if (level >= ctx->Const.MaxTextureLevels)
507 return NULL;
508 texIndex = TEXTURE_2D_INDEX;
509 break;
510 case GL_PROXY_TEXTURE_3D:
511 if (level >= ctx->Const.Max3DTextureLevels)
512 return NULL;
513 texIndex = TEXTURE_3D_INDEX;
514 break;
515 case GL_PROXY_TEXTURE_CUBE_MAP:
516 if (level >= ctx->Const.MaxCubeTextureLevels)
517 return NULL;
518 texIndex = TEXTURE_CUBE_INDEX;
519 break;
520 default:
521 return NULL;
522 }
523
524 texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level];
525 if (!texImage) {
526 texImage = ctx->Driver.NewTextureImage(ctx);
527 if (!texImage) {
528 _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
529 return NULL;
530 }
531 ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage;
532 /* Set the 'back' pointer */
533 texImage->TexObject = ctx->Texture.ProxyTex[texIndex];
534 }
535 return texImage;
536 }
537
538
539 /**
540 * Get the maximum number of allowed mipmap levels.
541 *
542 * \param ctx GL context.
543 * \param target texture target.
544 *
545 * \return the maximum number of allowed mipmap levels for the given
546 * texture target, or zero if passed a bad target.
547 *
548 * \sa gl_constants.
549 */
550 GLint
551 _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
552 {
553 switch (target) {
554 case GL_TEXTURE_1D:
555 case GL_PROXY_TEXTURE_1D:
556 case GL_TEXTURE_2D:
557 case GL_PROXY_TEXTURE_2D:
558 return ctx->Const.MaxTextureLevels;
559 case GL_TEXTURE_3D:
560 case GL_PROXY_TEXTURE_3D:
561 return ctx->Const.Max3DTextureLevels;
562 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
563 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
564 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
565 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
566 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
567 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
568 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
569 return ctx->Extensions.ARB_texture_cube_map
570 ? ctx->Const.MaxCubeTextureLevels : 0;
571 default:
572 return 0; /* bad target */
573 }
574 }
575
576
577 /**
578 * Return number of dimensions per mipmap level for the given texture target.
579 */
580 GLint
581 _mesa_get_texture_dimensions(GLenum target)
582 {
583 switch (target) {
584 case GL_TEXTURE_1D:
585 case GL_PROXY_TEXTURE_1D:
586 return 1;
587 case GL_TEXTURE_2D:
588 case GL_TEXTURE_CUBE_MAP:
589 case GL_PROXY_TEXTURE_2D:
590 case GL_PROXY_TEXTURE_CUBE_MAP:
591 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
592 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
593 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
594 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
595 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
596 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
597 return 2;
598 case GL_TEXTURE_3D:
599 case GL_PROXY_TEXTURE_3D:
600 return 3;
601 default:
602 _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
603 target);
604 return 2;
605 }
606 }
607
608
609
610
611 #if 000 /* not used anymore */
612 /*
613 * glTexImage[123]D can accept a NULL image pointer. In this case we
614 * create a texture image with unspecified image contents per the OpenGL
615 * spec.
616 */
617 static GLubyte *
618 make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
619 {
620 const GLint components = _mesa_components_in_format(format);
621 const GLint numPixels = width * height * depth;
622 GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
623
624 #ifdef DEBUG
625 /*
626 * Let's see if anyone finds this. If glTexImage2D() is called with
627 * a NULL image pointer then load the texture image with something
628 * interesting instead of leaving it indeterminate.
629 */
630 if (data) {
631 static const char message[8][32] = {
632 " X X XXXXX XXX X ",
633 " XX XX X X X X X ",
634 " X X X X X X X ",
635 " X X XXXX XXX XXXXX ",
636 " X X X X X X ",
637 " X X X X X X X ",
638 " X X XXXXX XXX X X ",
639 " "
640 };
641
642 GLubyte *imgPtr = data;
643 GLint h, i, j, k;
644 for (h = 0; h < depth; h++) {
645 for (i = 0; i < height; i++) {
646 GLint srcRow = 7 - (i % 8);
647 for (j = 0; j < width; j++) {
648 GLint srcCol = j % 32;
649 GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
650 for (k = 0; k < components; k++) {
651 *imgPtr++ = texel;
652 }
653 }
654 }
655 }
656 }
657 #endif
658
659 return data;
660 }
661 #endif
662
663
664
665 /**
666 * Set the size and format-related fields of a gl_texture_image struct
667 * to zero. This is used when a proxy texture test fails.
668 */
669 static void
670 clear_teximage_fields(struct gl_texture_image *img)
671 {
672 ASSERT(img);
673 img->_BaseFormat = 0;
674 img->InternalFormat = 0;
675 img->Border = 0;
676 img->Width = 0;
677 img->Height = 0;
678 img->Depth = 0;
679 img->Width2 = 0;
680 img->Height2 = 0;
681 img->Depth2 = 0;
682 img->WidthLog2 = 0;
683 img->HeightLog2 = 0;
684 img->DepthLog2 = 0;
685 img->TexFormat = MESA_FORMAT_NONE;
686 }
687
688
689 /**
690 * Initialize basic fields of the gl_texture_image struct.
691 *
692 * \param ctx GL context.
693 * \param img texture image structure to be initialized.
694 * \param width image width.
695 * \param height image height.
696 * \param depth image depth.
697 * \param border image border.
698 * \param internalFormat internal format.
699 * \param format the actual hardware format (one of MESA_FORMAT_*)
700 *
701 * Fills in the fields of \p img with the given information.
702 * Note: width, height and depth include the border.
703 */
704 void
705 _mesa_init_teximage_fields(struct gl_context *ctx,
706 struct gl_texture_image *img,
707 GLsizei width, GLsizei height, GLsizei depth,
708 GLint border, GLenum internalFormat,
709 gl_format format)
710 {
711 GLenum target;
712 ASSERT(img);
713 ASSERT(width >= 0);
714 ASSERT(height >= 0);
715 ASSERT(depth >= 0);
716
717 target = img->TexObject->Target;
718 img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
719 ASSERT(img->_BaseFormat > 0);
720 img->InternalFormat = internalFormat;
721 img->Border = border;
722 img->Width = width;
723 img->Height = height;
724 img->Depth = depth;
725
726 img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */
727 img->WidthLog2 = _mesa_logbase2(img->Width2);
728
729 switch(target) {
730 case GL_TEXTURE_1D:
731 case GL_PROXY_TEXTURE_1D:
732 if (height == 0)
733 img->Height2 = 0;
734 else
735 img->Height2 = 1;
736 img->HeightLog2 = 0;
737 if (depth == 0)
738 img->Depth2 = 0;
739 else
740 img->Depth2 = 1;
741 img->DepthLog2 = 0;
742 break;
743 case GL_TEXTURE_2D:
744 case GL_TEXTURE_CUBE_MAP:
745 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
746 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
747 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
748 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
749 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
750 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
751 case GL_PROXY_TEXTURE_2D:
752 case GL_PROXY_TEXTURE_CUBE_MAP:
753 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
754 img->HeightLog2 = _mesa_logbase2(img->Height2);
755 if (depth == 0)
756 img->Depth2 = 0;
757 else
758 img->Depth2 = 1;
759 img->DepthLog2 = 0;
760 break;
761 case GL_TEXTURE_3D:
762 case GL_PROXY_TEXTURE_3D:
763 img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
764 img->HeightLog2 = _mesa_logbase2(img->Height2);
765 img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */
766 img->DepthLog2 = _mesa_logbase2(img->Depth2);
767 break;
768 default:
769 _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()",
770 target);
771 }
772
773 img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
774 img->TexFormat = format;
775 }
776
777
778 /**
779 * Free and clear fields of the gl_texture_image struct.
780 *
781 * \param ctx GL context.
782 * \param texImage texture image structure to be cleared.
783 *
784 * After the call, \p texImage will have no data associated with it. Its
785 * fields are cleared so that its parent object will test incomplete.
786 */
787 void
788 _mesa_clear_texture_image(struct gl_context *ctx,
789 struct gl_texture_image *texImage)
790 {
791 ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
792 clear_teximage_fields(texImage);
793 }
794
795
796 /**
797 * This is the fallback for Driver.TestProxyTexImage(). Test the texture
798 * level, width, height and depth against the ctx->Const limits for textures.
799 *
800 * A hardware driver might override this function if, for example, the
801 * max 3D texture size is 512x512x64 (i.e. not a cube).
802 *
803 * Note that width, height, depth == 0 is not an error. However, a
804 * texture with zero width/height/depth will be considered "incomplete"
805 * and texturing will effectively be disabled.
806 *
807 * \param target one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
808 * GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
809 * GL_PROXY_TEXTURE_CUBE_MAP_ARB.
810 * \param level as passed to glTexImage
811 * \param internalFormat as passed to glTexImage
812 * \param format as passed to glTexImage
813 * \param type as passed to glTexImage
814 * \param width as passed to glTexImage
815 * \param height as passed to glTexImage
816 * \param depth as passed to glTexImage
817 * \param border as passed to glTexImage
818 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
819 */
820 GLboolean
821 _mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
822 GLint internalFormat, GLenum format, GLenum type,
823 GLint width, GLint height, GLint depth, GLint border)
824 {
825 GLint maxSize;
826
827 (void) internalFormat;
828 (void) format;
829 (void) type;
830
831 switch (target) {
832 case GL_PROXY_TEXTURE_1D:
833 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
834 if (width < 2 * border || width > 2 * border + maxSize)
835 return GL_FALSE;
836 if (level >= ctx->Const.MaxTextureLevels)
837 return GL_FALSE;
838 if (!ctx->Extensions.ARB_texture_non_power_of_two) {
839 if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
840 return GL_FALSE;
841 }
842 return GL_TRUE;
843
844 case GL_PROXY_TEXTURE_2D:
845 maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
846 if (width < 2 * border || width > 2 * border + maxSize)
847 return GL_FALSE;
848 if (height < 2 * border || height > 2 * border + maxSize)
849 return GL_FALSE;
850 if (level >= ctx->Const.MaxTextureLevels)
851 return GL_FALSE;
852 if (!ctx->Extensions.ARB_texture_non_power_of_two) {
853 if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
854 return GL_FALSE;
855 if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
856 return GL_FALSE;
857 }
858 return GL_TRUE;
859
860 case GL_PROXY_TEXTURE_3D:
861 maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
862 if (width < 2 * border || width > 2 * border + maxSize)
863 return GL_FALSE;
864 if (height < 2 * border || height > 2 * border + maxSize)
865 return GL_FALSE;
866 if (depth < 2 * border || depth > 2 * border + maxSize)
867 return GL_FALSE;
868 if (level >= ctx->Const.Max3DTextureLevels)
869 return GL_FALSE;
870 if (!ctx->Extensions.ARB_texture_non_power_of_two) {
871 if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
872 return GL_FALSE;
873 if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
874 return GL_FALSE;
875 if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border))
876 return GL_FALSE;
877 }
878 return GL_TRUE;
879
880 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
881 maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
882 if (width < 2 * border || width > 2 * border + maxSize)
883 return GL_FALSE;
884 if (height < 2 * border || height > 2 * border + maxSize)
885 return GL_FALSE;
886 if (level >= ctx->Const.MaxCubeTextureLevels)
887 return GL_FALSE;
888 if (!ctx->Extensions.ARB_texture_non_power_of_two) {
889 if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
890 return GL_FALSE;
891 if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
892 return GL_FALSE;
893 }
894 return GL_TRUE;
895
896 default:
897 _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
898 return GL_FALSE;
899 }
900 }
901
902
903 /**
904 * Check if the memory used by the texture would exceed the driver's limit.
905 * This lets us support a max 3D texture size of 8K (for example) but
906 * prevents allocating a full 8K x 8K x 8K texture.
907 * XXX this could be rolled into the proxy texture size test (above) but
908 * we don't have the actual texture internal format at that point.
909 */
910 static GLboolean
911 legal_texture_size(struct gl_context *ctx, gl_format format,
912 GLint width, GLint height, GLint depth)
913 {
914 uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
915 uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
916 return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
917 }
918
919 /**
920 * Check if the given texture target value is legal for a
921 * glTexImage1/2/3D call.
922 */
923 static GLboolean
924 legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
925 {
926 switch (dims) {
927 case 1:
928 switch (target) {
929 case GL_TEXTURE_1D:
930 case GL_PROXY_TEXTURE_1D:
931 return GL_TRUE;
932 default:
933 return GL_FALSE;
934 }
935 case 2:
936 switch (target) {
937 case GL_TEXTURE_2D:
938 case GL_PROXY_TEXTURE_2D:
939 return GL_TRUE;
940 case GL_PROXY_TEXTURE_CUBE_MAP:
941 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
942 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
943 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
944 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
945 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
946 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
947 return ctx->Extensions.ARB_texture_cube_map;
948 default:
949 return GL_FALSE;
950 }
951 case 3:
952 switch (target) {
953 case GL_TEXTURE_3D:
954 case GL_PROXY_TEXTURE_3D:
955 return GL_TRUE;
956 default:
957 return GL_FALSE;
958 }
959 default:
960 _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
961 return GL_FALSE;
962 }
963 }
964
965
966 /**
967 * Check if the given texture target value is legal for a
968 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
969 * The difference compared to legal_teximage_target() above is that
970 * proxy targets are not supported.
971 */
972 static GLboolean
973 legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
974 {
975 switch (dims) {
976 case 1:
977 return target == GL_TEXTURE_1D;
978 case 2:
979 switch (target) {
980 case GL_TEXTURE_2D:
981 return GL_TRUE;
982 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
983 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
984 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
985 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
986 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
987 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
988 return ctx->Extensions.ARB_texture_cube_map;
989 default:
990 return GL_FALSE;
991 }
992 case 3:
993 switch (target) {
994 case GL_TEXTURE_3D:
995 return GL_TRUE;
996 default:
997 return GL_FALSE;
998 }
999 default:
1000 _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
1001 dims);
1002 return GL_FALSE;
1003 }
1004 }
1005
1006
1007 /**
1008 * Helper function to determine if a texture object is mutable (in terms
1009 * of GL_ARB_texture_storage).
1010 */
1011 static GLboolean
1012 mutable_tex_object(struct gl_context *ctx, GLenum target)
1013 {
1014 if (ctx->Extensions.ARB_texture_storage) {
1015 struct gl_texture_object *texObj =
1016 _mesa_get_current_tex_object(ctx, target);
1017 return !texObj->Immutable;
1018 }
1019 return GL_TRUE;
1020 }
1021
1022
1023
1024 /**
1025 * Test the glTexImage[123]D() parameters for errors.
1026 *
1027 * \param ctx GL context.
1028 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1029 * \param target texture target given by the user.
1030 * \param level image level given by the user.
1031 * \param internalFormat internal format given by the user.
1032 * \param format pixel data format given by the user.
1033 * \param type pixel data type given by the user.
1034 * \param width image width given by the user.
1035 * \param height image height given by the user.
1036 * \param depth image depth given by the user.
1037 * \param border image border given by the user.
1038 *
1039 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1040 *
1041 * Verifies each of the parameters against the constants specified in
1042 * __struct gl_contextRec::Const and the supported extensions, and according
1043 * to the OpenGL specification.
1044 */
1045 static GLboolean
1046 texture_error_check( struct gl_context *ctx,
1047 GLuint dimensions, GLenum target,
1048 GLint level, GLint internalFormat,
1049 GLenum format, GLenum type,
1050 GLint width, GLint height,
1051 GLint depth, GLint border )
1052 {
1053 const GLenum proxyTarget = get_proxy_target(target);
1054 const GLboolean isProxy = target == proxyTarget;
1055 GLboolean sizeOK = GL_TRUE;
1056 GLboolean colorFormat;
1057 GLenum err;
1058
1059 /* Even though there are no color-index textures, we still have to support
1060 * uploading color-index data and remapping it to RGB via the
1061 * GL_PIXEL_MAP_I_TO_[RGBA] tables.
1062 */
1063 const GLboolean indexFormat = (format == GL_COLOR_INDEX);
1064
1065 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1066 if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1067 if (!isProxy) {
1068 _mesa_error(ctx, GL_INVALID_VALUE,
1069 "glTexImage%dD(level=%d)", dimensions, level);
1070 }
1071 return GL_TRUE;
1072 }
1073
1074 /* Check border */
1075 if (border < 0 || border > 1) {
1076 if (!isProxy) {
1077 _mesa_error(ctx, GL_INVALID_VALUE,
1078 "glTexImage%dD(border=%d)", dimensions, border);
1079 }
1080 return GL_TRUE;
1081 }
1082
1083 if (width < 0 || height < 0 || depth < 0) {
1084 if (!isProxy) {
1085 _mesa_error(ctx, GL_INVALID_VALUE,
1086 "glTexImage%dD(width, height or depth < 0)", dimensions);
1087 }
1088 return GL_TRUE;
1089 }
1090
1091 /* Do this simple check before calling the TestProxyTexImage() function */
1092 if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
1093 sizeOK = (width == height);
1094 }
1095
1096 /*
1097 * Use the proxy texture driver hook to see if the size/level/etc are
1098 * legal.
1099 */
1100 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
1101 internalFormat, format,
1102 type, width, height,
1103 depth, border);
1104 if (!sizeOK) {
1105 if (!isProxy) {
1106 _mesa_error(ctx, GL_INVALID_VALUE,
1107 "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
1108 dimensions, level, width, height, depth);
1109 }
1110 return GL_TRUE;
1111 }
1112
1113 /* Check internalFormat */
1114 if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
1115 if (!isProxy) {
1116 _mesa_error(ctx, GL_INVALID_VALUE,
1117 "glTexImage%dD(internalFormat=%s)",
1118 dimensions, _mesa_lookup_enum_by_nr(internalFormat));
1119 }
1120 return GL_TRUE;
1121 }
1122
1123 /* Check incoming image format and type */
1124 err = _mesa_error_check_format_and_type(ctx, format, type);
1125 if (err != GL_NO_ERROR) {
1126 if (!isProxy) {
1127 _mesa_error(ctx, err,
1128 "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
1129 dimensions, format, type);
1130 }
1131 return GL_TRUE;
1132 }
1133
1134 /* make sure internal format and format basically agree */
1135 colorFormat = _mesa_is_color_format(format);
1136 if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
1137 (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
1138 (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
1139 (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
1140 if (!isProxy)
1141 _mesa_error(ctx, GL_INVALID_OPERATION,
1142 "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
1143 dimensions, internalFormat, format);
1144 return GL_TRUE;
1145 }
1146
1147 /* additional checks for ycbcr textures */
1148 if (internalFormat == GL_YCBCR_MESA) {
1149 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1150 if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
1151 type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
1152 char message[100];
1153 _mesa_snprintf(message, sizeof(message),
1154 "glTexImage%dD(format/type YCBCR mismatch", dimensions);
1155 _mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
1156 return GL_TRUE; /* error */
1157 }
1158 if (target != GL_TEXTURE_2D &&
1159 target != GL_PROXY_TEXTURE_2D) {
1160 if (!isProxy)
1161 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
1162 return GL_TRUE;
1163 }
1164 if (border != 0) {
1165 if (!isProxy) {
1166 char message[100];
1167 _mesa_snprintf(message, sizeof(message),
1168 "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
1169 dimensions, border);
1170 _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
1171 }
1172 return GL_TRUE;
1173 }
1174 }
1175
1176 /* additional checks for depth textures */
1177 if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
1178 /* Only 1D, 2D, rect, array and cube textures supported, not 3D
1179 * Cubemaps are only supported for GL version > 3.0 or with EXT_gpu_shader4 */
1180 if (target != GL_TEXTURE_1D &&
1181 target != GL_PROXY_TEXTURE_1D &&
1182 target != GL_TEXTURE_2D &&
1183 target != GL_PROXY_TEXTURE_2D &&
1184 !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) &&
1185 (ctx->VersionMajor >= 3 || ctx->Extensions.EXT_gpu_shader4))) {
1186 if (!isProxy)
1187 _mesa_error(ctx, GL_INVALID_ENUM,
1188 "glTexImage(target/internalFormat)");
1189 return GL_TRUE;
1190 }
1191 }
1192
1193 /* additional checks for integer textures */
1194 if ((ctx->VersionMajor >= 3 || ctx->Extensions.EXT_texture_integer) &&
1195 (_mesa_is_integer_format(format) !=
1196 _mesa_is_integer_format(internalFormat))) {
1197 if (!isProxy) {
1198 _mesa_error(ctx, GL_INVALID_OPERATION,
1199 "glTexImage%dD(integer/non-integer format mismatch)",
1200 dimensions);
1201 }
1202 return GL_TRUE;
1203 }
1204
1205 if (!mutable_tex_object(ctx, target)) {
1206 _mesa_error(ctx, GL_INVALID_OPERATION,
1207 "glTexImage%dD(immutable texture)", dimensions);
1208 return GL_TRUE;
1209 }
1210
1211 /* if we get here, the parameters are OK */
1212 return GL_FALSE;
1213 }
1214
1215
1216 /**
1217 * Test glTexSubImage[123]D() parameters for errors.
1218 *
1219 * \param ctx GL context.
1220 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1221 * \param target texture target given by the user.
1222 * \param level image level given by the user.
1223 * \param xoffset sub-image x offset given by the user.
1224 * \param yoffset sub-image y offset given by the user.
1225 * \param zoffset sub-image z offset given by the user.
1226 * \param format pixel data format given by the user.
1227 * \param type pixel data type given by the user.
1228 * \param width image width given by the user.
1229 * \param height image height given by the user.
1230 * \param depth image depth given by the user.
1231 *
1232 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1233 *
1234 * Verifies each of the parameters against the constants specified in
1235 * __struct gl_contextRec::Const and the supported extensions, and according
1236 * to the OpenGL specification.
1237 */
1238 static GLboolean
1239 subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
1240 GLenum target, GLint level,
1241 GLint xoffset, GLint yoffset, GLint zoffset,
1242 GLint width, GLint height, GLint depth,
1243 GLenum format, GLenum type )
1244 {
1245 GLenum err;
1246
1247 /* Basic level check */
1248 if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1249 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
1250 return GL_TRUE;
1251 }
1252
1253 /* Check for negative sizes */
1254 if (width < 0) {
1255 _mesa_error(ctx, GL_INVALID_VALUE,
1256 "glTexSubImage%dD(width=%d)", dimensions, width);
1257 return GL_TRUE;
1258 }
1259 if (height < 0 && dimensions > 1) {
1260 _mesa_error(ctx, GL_INVALID_VALUE,
1261 "glTexSubImage%dD(height=%d)", dimensions, height);
1262 return GL_TRUE;
1263 }
1264 if (depth < 0 && dimensions > 2) {
1265 _mesa_error(ctx, GL_INVALID_VALUE,
1266 "glTexSubImage%dD(depth=%d)", dimensions, depth);
1267 return GL_TRUE;
1268 }
1269
1270 err = _mesa_error_check_format_and_type(ctx, format, type);
1271 if (err != GL_NO_ERROR) {
1272 _mesa_error(ctx, err,
1273 "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)",
1274 dimensions, format, type);
1275 return GL_TRUE;
1276 }
1277
1278 return GL_FALSE;
1279 }
1280
1281
1282 /**
1283 * Do second part of glTexSubImage which depends on the destination texture.
1284 * \return GL_TRUE if error recorded, GL_FALSE otherwise
1285 */
1286 static GLboolean
1287 subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
1288 GLenum target, GLint level,
1289 GLint xoffset, GLint yoffset, GLint zoffset,
1290 GLint width, GLint height, GLint depth,
1291 GLenum format, GLenum type,
1292 const struct gl_texture_image *destTex )
1293 {
1294 if (!destTex) {
1295 /* undefined image level */
1296 _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
1297 return GL_TRUE;
1298 }
1299
1300 if (xoffset < -((GLint)destTex->Border)) {
1301 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
1302 dimensions);
1303 return GL_TRUE;
1304 }
1305 if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
1306 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
1307 dimensions);
1308 return GL_TRUE;
1309 }
1310 if (dimensions > 1) {
1311 if (yoffset < -((GLint)destTex->Border)) {
1312 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
1313 dimensions);
1314 return GL_TRUE;
1315 }
1316 if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
1317 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
1318 dimensions);
1319 return GL_TRUE;
1320 }
1321 }
1322 if (dimensions > 2) {
1323 if (zoffset < -((GLint)destTex->Border)) {
1324 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
1325 return GL_TRUE;
1326 }
1327 if (zoffset + depth > (GLint) (destTex->Depth + destTex->Border)) {
1328 _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
1329 return GL_TRUE;
1330 }
1331 }
1332
1333 if (ctx->VersionMajor >= 3 || ctx->Extensions.EXT_texture_integer) {
1334 /* both source and dest must be integer-valued, or neither */
1335 if (_mesa_is_format_integer_color(destTex->TexFormat) !=
1336 _mesa_is_integer_format(format)) {
1337 _mesa_error(ctx, GL_INVALID_OPERATION,
1338 "glTexSubImage%dD(integer/non-integer format mismatch)",
1339 dimensions);
1340 return GL_TRUE;
1341 }
1342 }
1343
1344 return GL_FALSE;
1345 }
1346
1347
1348 /**
1349 * Test glCopyTexImage[12]D() parameters for errors.
1350 *
1351 * \param ctx GL context.
1352 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1353 * \param target texture target given by the user.
1354 * \param level image level given by the user.
1355 * \param internalFormat internal format given by the user.
1356 * \param width image width given by the user.
1357 * \param height image height given by the user.
1358 * \param border texture border.
1359 *
1360 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1361 *
1362 * Verifies each of the parameters against the constants specified in
1363 * __struct gl_contextRec::Const and the supported extensions, and according
1364 * to the OpenGL specification.
1365 */
1366 static GLboolean
1367 copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
1368 GLenum target, GLint level, GLint internalFormat,
1369 GLint width, GLint height, GLint border )
1370 {
1371 const GLenum proxyTarget = get_proxy_target(target);
1372 const GLenum type = GL_FLOAT;
1373 GLboolean sizeOK;
1374 GLint baseFormat;
1375
1376 /* check target */
1377 if (!legal_texsubimage_target(ctx, dimensions, target)) {
1378 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
1379 dimensions, _mesa_lookup_enum_by_nr(target));
1380 return GL_TRUE;
1381 }
1382
1383 /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1384 if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1385 _mesa_error(ctx, GL_INVALID_VALUE,
1386 "glCopyTexImage%dD(level=%d)", dimensions, level);
1387 return GL_TRUE;
1388 }
1389
1390 /* Check border */
1391 if (border < 0 || border > 1) {
1392 return GL_TRUE;
1393 }
1394
1395 baseFormat = _mesa_base_tex_format(ctx, internalFormat);
1396 if (baseFormat < 0) {
1397 _mesa_error(ctx, GL_INVALID_VALUE,
1398 "glCopyTexImage%dD(internalFormat)", dimensions);
1399 return GL_TRUE;
1400 }
1401
1402 if (!_mesa_source_buffer_exists(ctx, baseFormat)) {
1403 _mesa_error(ctx, GL_INVALID_OPERATION,
1404 "glCopyTexImage%dD(missing readbuffer)", dimensions);
1405 return GL_TRUE;
1406 }
1407
1408 /* From the EXT_texture_integer spec:
1409 *
1410 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
1411 * if the texture internalformat is an integer format and the read color
1412 * buffer is not an integer format, or if the internalformat is not an
1413 * integer format and the read color buffer is an integer format."
1414 */
1415 if (_mesa_is_color_format(internalFormat)) {
1416 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1417
1418 if (_mesa_is_integer_format(rb->InternalFormat) !=
1419 _mesa_is_integer_format(internalFormat)) {
1420 _mesa_error(ctx, GL_INVALID_OPERATION,
1421 "glCopyTexImage%dD(integer vs non-integer)", dimensions);
1422 return GL_TRUE;
1423 }
1424 }
1425
1426 /* Do size, level checking */
1427 sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
1428 ? (width == height) : 1;
1429
1430 sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
1431 internalFormat, baseFormat,
1432 type, width, height,
1433 1, border);
1434
1435 if (!sizeOK) {
1436 if (dimensions == 1) {
1437 _mesa_error(ctx, GL_INVALID_VALUE,
1438 "glCopyTexImage1D(width=%d)", width);
1439 }
1440 else {
1441 ASSERT(dimensions == 2);
1442 _mesa_error(ctx, GL_INVALID_VALUE,
1443 "glCopyTexImage2D(width=%d, height=%d)", width, height);
1444 }
1445 return GL_TRUE;
1446 }
1447
1448 if (!mutable_tex_object(ctx, target)) {
1449 _mesa_error(ctx, GL_INVALID_OPERATION,
1450 "glCopyTexImage%dD(immutable texture)", dimensions);
1451 return GL_TRUE;
1452 }
1453
1454 /* if we get here, the parameters are OK */
1455 return GL_FALSE;
1456 }
1457
1458
1459 /**
1460 * Test glCopyTexSubImage[12]D() parameters for errors.
1461 * Note that this is the first part of error checking.
1462 * See also copytexsubimage_error_check2() below for the second part.
1463 *
1464 * \param ctx GL context.
1465 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1466 * \param target texture target given by the user.
1467 * \param level image level given by the user.
1468 *
1469 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1470 */
1471 static GLboolean
1472 copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
1473 GLenum target, GLint level)
1474 {
1475 /* check target (proxies not allowed) */
1476 if (!legal_texsubimage_target(ctx, dimensions, target)) {
1477 _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
1478 dimensions, _mesa_lookup_enum_by_nr(target));
1479 return GL_TRUE;
1480 }
1481
1482 /* Check level */
1483 if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1484 _mesa_error(ctx, GL_INVALID_VALUE,
1485 "glCopyTexSubImage%dD(level=%d)", dimensions, level);
1486 return GL_TRUE;
1487 }
1488
1489 return GL_FALSE;
1490 }
1491
1492
1493 /**
1494 * Second part of error checking for glCopyTexSubImage[12]D().
1495 * \param xoffset sub-image x offset given by the user.
1496 * \param yoffset sub-image y offset given by the user.
1497 * \param zoffset sub-image z offset given by the user.
1498 * \param width image width given by the user.
1499 * \param height image height given by the user.
1500 */
1501 static GLboolean
1502 copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
1503 GLenum target, GLint level,
1504 GLint xoffset, GLint yoffset, GLint zoffset,
1505 GLsizei width, GLsizei height,
1506 const struct gl_texture_image *teximage )
1507 {
1508 /* check that dest tex image exists */
1509 if (!teximage) {
1510 _mesa_error(ctx, GL_INVALID_OPERATION,
1511 "glCopyTexSubImage%dD(undefined texture level: %d)",
1512 dimensions, level);
1513 return GL_TRUE;
1514 }
1515
1516 /* Check size */
1517 if (width < 0) {
1518 _mesa_error(ctx, GL_INVALID_VALUE,
1519 "glCopyTexSubImage%dD(width=%d)", dimensions, width);
1520 return GL_TRUE;
1521 }
1522 if (dimensions > 1 && height < 0) {
1523 _mesa_error(ctx, GL_INVALID_VALUE,
1524 "glCopyTexSubImage%dD(height=%d)", dimensions, height);
1525 return GL_TRUE;
1526 }
1527
1528 /* check x/y offsets */
1529 if (xoffset < -((GLint)teximage->Border)) {
1530 _mesa_error(ctx, GL_INVALID_VALUE,
1531 "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
1532 return GL_TRUE;
1533 }
1534 if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
1535 _mesa_error(ctx, GL_INVALID_VALUE,
1536 "glCopyTexSubImage%dD(xoffset+width)", dimensions);
1537 return GL_TRUE;
1538 }
1539 if (dimensions > 1) {
1540 if (yoffset < -((GLint)teximage->Border)) {
1541 _mesa_error(ctx, GL_INVALID_VALUE,
1542 "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
1543 return GL_TRUE;
1544 }
1545 /* NOTE: we're adding the border here, not subtracting! */
1546 if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) {
1547 _mesa_error(ctx, GL_INVALID_VALUE,
1548 "glCopyTexSubImage%dD(yoffset+height)", dimensions);
1549 return GL_TRUE;
1550 }
1551 }
1552
1553 /* check z offset */
1554 if (dimensions > 2) {
1555 if (zoffset < -((GLint)teximage->Border)) {
1556 _mesa_error(ctx, GL_INVALID_VALUE,
1557 "glCopyTexSubImage%dD(zoffset)", dimensions);
1558 return GL_TRUE;
1559 }
1560 if (zoffset > (GLint) (teximage->Depth + teximage->Border)) {
1561 _mesa_error(ctx, GL_INVALID_VALUE,
1562 "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
1563 return GL_TRUE;
1564 }
1565 }
1566
1567 if (teximage->InternalFormat == GL_YCBCR_MESA) {
1568 _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
1569 return GL_TRUE;
1570 }
1571
1572 if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
1573 _mesa_error(ctx, GL_INVALID_OPERATION,
1574 "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)",
1575 dimensions, teximage->_BaseFormat);
1576 return GL_TRUE;
1577 }
1578
1579 /* From the EXT_texture_integer spec:
1580 *
1581 * "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
1582 * if the texture internalformat is an integer format and the read color
1583 * buffer is not an integer format, or if the internalformat is not an
1584 * integer format and the read color buffer is an integer format."
1585 */
1586 if (_mesa_is_color_format(teximage->InternalFormat)) {
1587 struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
1588
1589 if (_mesa_is_format_integer_color(rb->Format) !=
1590 _mesa_is_format_integer_color(teximage->TexFormat)) {
1591 _mesa_error(ctx, GL_INVALID_OPERATION,
1592 "glCopyTexImage%dD(integer vs non-integer)", dimensions);
1593 return GL_TRUE;
1594 }
1595 }
1596
1597 /* if we get here, the parameters are OK */
1598 return GL_FALSE;
1599 }
1600
1601
1602 /** Callback info for walking over FBO hash table */
1603 struct cb_info
1604 {
1605 struct gl_context *ctx;
1606 struct gl_texture_object *texObj;
1607 GLuint level, face;
1608 };
1609
1610 /** Debug helper: override the user-requested internal format */
1611 static GLenum
1612 override_internal_format(GLenum internalFormat, GLint width, GLint height)
1613 {
1614 #if 0
1615 if (internalFormat == GL_RGBA16F_ARB ||
1616 internalFormat == GL_RGBA32F_ARB) {
1617 printf("Convert rgba float tex to int %d x %d\n", width, height);
1618 return GL_RGBA;
1619 }
1620 else if (internalFormat == GL_RGB16F_ARB ||
1621 internalFormat == GL_RGB32F_ARB) {
1622 printf("Convert rgb float tex to int %d x %d\n", width, height);
1623 return GL_RGB;
1624 }
1625 else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB ||
1626 internalFormat == GL_LUMINANCE_ALPHA32F_ARB) {
1627 printf("Convert luminance float tex to int %d x %d\n", width, height);
1628 return GL_LUMINANCE_ALPHA;
1629 }
1630 else if (internalFormat == GL_LUMINANCE16F_ARB ||
1631 internalFormat == GL_LUMINANCE32F_ARB) {
1632 printf("Convert luminance float tex to int %d x %d\n", width, height);
1633 return GL_LUMINANCE;
1634 }
1635 else if (internalFormat == GL_ALPHA16F_ARB ||
1636 internalFormat == GL_ALPHA32F_ARB) {
1637 printf("Convert luminance float tex to int %d x %d\n", width, height);
1638 return GL_ALPHA;
1639 }
1640 else {
1641 return internalFormat;
1642 }
1643 #else
1644 return internalFormat;
1645 #endif
1646 }
1647
1648
1649 /**
1650 * Choose the actual hardware format for a texture image.
1651 * Try to use the same format as the previous image level when possible.
1652 * Otherwise, ask the driver for the best format.
1653 * It's important to try to choose a consistant format for all levels
1654 * for efficient texture memory layout/allocation. In particular, this
1655 * comes up during automatic mipmap generation.
1656 */
1657 gl_format
1658 _mesa_choose_texture_format(struct gl_context *ctx,
1659 struct gl_texture_object *texObj,
1660 GLenum target, GLint level,
1661 GLenum internalFormat, GLenum format, GLenum type)
1662 {
1663 gl_format f;
1664
1665 /* see if we've already chosen a format for the previous level */
1666 if (level > 0) {
1667 struct gl_texture_image *prevImage =
1668 _mesa_select_tex_image(ctx, texObj, target, level - 1);
1669 /* See if the prev level is defined and has an internal format which
1670 * matches the new internal format.
1671 */
1672 if (prevImage &&
1673 prevImage->Width > 0 &&
1674 prevImage->InternalFormat == internalFormat) {
1675 /* use the same format */
1676 ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE);
1677 return prevImage->TexFormat;
1678 }
1679 }
1680
1681 /* choose format from scratch */
1682 f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
1683 ASSERT(f != MESA_FORMAT_NONE);
1684 return f;
1685 }
1686
1687 /**
1688 * Adjust pixel unpack params and image dimensions to strip off the
1689 * texture border.
1690 *
1691 * Gallium and intel don't support texture borders. They've seldem been used
1692 * and seldom been implemented correctly anyway.
1693 *
1694 * \param unpackNew returns the new pixel unpack parameters
1695 */
1696 static void
1697 strip_texture_border(GLint *border,
1698 GLint *width, GLint *height, GLint *depth,
1699 const struct gl_pixelstore_attrib *unpack,
1700 struct gl_pixelstore_attrib *unpackNew)
1701 {
1702 assert(*border > 0); /* sanity check */
1703
1704 *unpackNew = *unpack;
1705
1706 if (unpackNew->RowLength == 0)
1707 unpackNew->RowLength = *width;
1708
1709 if (depth && unpackNew->ImageHeight == 0)
1710 unpackNew->ImageHeight = *height;
1711
1712 unpackNew->SkipPixels += *border;
1713 if (height)
1714 unpackNew->SkipRows += *border;
1715 if (depth)
1716 unpackNew->SkipImages += *border;
1717
1718 assert(*width >= 3);
1719 *width = *width - 2 * *border;
1720 if (height && *height >= 3)
1721 *height = *height - 2 * *border;
1722 if (depth && *depth >= 3)
1723 *depth = *depth - 2 * *border;
1724 *border = 0;
1725 }
1726
1727 /**
1728 * Common code to implement all the glTexImage1D/2D/3D functions.
1729 */
1730 static void
1731 teximage(struct gl_context *ctx, GLuint dims,
1732 GLenum target, GLint level, GLint internalFormat,
1733 GLsizei width, GLsizei height, GLsizei depth,
1734 GLint border, GLenum format, GLenum type,
1735 const GLvoid *pixels)
1736 {
1737 GLboolean error;
1738 struct gl_pixelstore_attrib unpack_no_border;
1739 const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
1740
1741 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1742
1743 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1744 _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
1745 dims,
1746 _mesa_lookup_enum_by_nr(target), level,
1747 _mesa_lookup_enum_by_nr(internalFormat),
1748 width, height, depth, border,
1749 _mesa_lookup_enum_by_nr(format),
1750 _mesa_lookup_enum_by_nr(type), pixels);
1751
1752 internalFormat = override_internal_format(internalFormat, width, height);
1753
1754 /* target error checking */
1755 if (!legal_teximage_target(ctx, dims, target)) {
1756 _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
1757 dims, _mesa_lookup_enum_by_nr(target));
1758 return;
1759 }
1760
1761 /* general error checking */
1762 error = texture_error_check(ctx, dims, target, level, internalFormat,
1763 format, type, width, height, depth, border);
1764
1765 if (_mesa_is_proxy_texture(target)) {
1766 /* Proxy texture: just clear or set state depending on error checking */
1767 struct gl_texture_image *texImage =
1768 _mesa_get_proxy_tex_image(ctx, target, level);
1769
1770 if (error) {
1771 /* when error, clear all proxy texture image parameters */
1772 if (texImage)
1773 clear_teximage_fields(texImage);
1774 }
1775 else {
1776 /* no error, set the tex image parameters */
1777 struct gl_texture_object *texObj =
1778 _mesa_get_current_tex_object(ctx, target);
1779 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
1780 target, level,
1781 internalFormat,
1782 format, type);
1783
1784 if (legal_texture_size(ctx, texFormat, width, height, depth)) {
1785 _mesa_init_teximage_fields(ctx, texImage, width, height,
1786 depth, border, internalFormat,
1787 texFormat);
1788 }
1789 else if (texImage) {
1790 clear_teximage_fields(texImage);
1791 }
1792 }
1793 }
1794 else {
1795 /* non-proxy target */
1796 struct gl_texture_object *texObj;
1797 struct gl_texture_image *texImage;
1798
1799 if (error) {
1800 return; /* error was recorded */
1801 }
1802
1803 /* Allow a hardware driver to just strip out the border, to provide
1804 * reliable but slightly incorrect hardware rendering instead of
1805 * rarely-tested software fallback rendering.
1806 */
1807 if (border && ctx->Const.StripTextureBorder) {
1808 strip_texture_border(&border, &width, &height, &depth, unpack,
1809 &unpack_no_border);
1810 unpack = &unpack_no_border;
1811 }
1812
1813 if (ctx->NewState & _NEW_PIXEL)
1814 _mesa_update_state(ctx);
1815
1816 texObj = _mesa_get_current_tex_object(ctx, target);
1817
1818 _mesa_lock_texture(ctx, texObj);
1819 {
1820 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
1821
1822 if (!texImage) {
1823 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
1824 }
1825 else {
1826 gl_format texFormat;
1827
1828 ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
1829
1830 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
1831 internalFormat, format,
1832 type);
1833
1834 if (legal_texture_size(ctx, texFormat, width, height, depth)) {
1835 _mesa_init_teximage_fields(ctx, texImage,
1836 width, height, depth,
1837 border, internalFormat, texFormat);
1838
1839 /* Give the texture to the driver. <pixels> may be null. */
1840 ASSERT(ctx->Driver.TexImage3D);
1841 switch (dims) {
1842 case 1:
1843 ctx->Driver.TexImage1D(ctx, texImage, internalFormat,
1844 width, border, format,
1845 type, pixels, unpack);
1846 break;
1847 case 2:
1848 ctx->Driver.TexImage2D(ctx, texImage, internalFormat,
1849 width, height, border, format,
1850 type, pixels, unpack);
1851 break;
1852 case 3:
1853 ctx->Driver.TexImage3D(ctx, texImage, internalFormat,
1854 width, height, depth, border, format,
1855 type, pixels, unpack);
1856 break;
1857 default:
1858 _mesa_problem(ctx, "invalid dims=%u in teximage()", dims);
1859 }
1860
1861 /* state update */
1862 texObj->_Complete = GL_FALSE;
1863 ctx->NewState |= _NEW_TEXTURE;
1864 }
1865 else {
1866 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
1867 }
1868 }
1869 }
1870 _mesa_unlock_texture(ctx, texObj);
1871 }
1872 }
1873
1874
1875 /*
1876 * Called from the API. Note that width includes the border.
1877 */
1878 void GLAPIENTRY
1879 _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
1880 GLsizei width, GLint border, GLenum format,
1881 GLenum type, const GLvoid *pixels )
1882 {
1883 GET_CURRENT_CONTEXT(ctx);
1884 teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
1885 border, format, type, pixels);
1886 }
1887
1888
1889 void GLAPIENTRY
1890 _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
1891 GLsizei width, GLsizei height, GLint border,
1892 GLenum format, GLenum type,
1893 const GLvoid *pixels )
1894 {
1895 GET_CURRENT_CONTEXT(ctx);
1896 teximage(ctx, 2, target, level, internalFormat, width, height, 1,
1897 border, format, type, pixels);
1898 }
1899
1900
1901 /*
1902 * Called by the API or display list executor.
1903 * Note that width and height include the border.
1904 */
1905 void GLAPIENTRY
1906 _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
1907 GLsizei width, GLsizei height, GLsizei depth,
1908 GLint border, GLenum format, GLenum type,
1909 const GLvoid *pixels )
1910 {
1911 GET_CURRENT_CONTEXT(ctx);
1912 teximage(ctx, 3, target, level, internalFormat, width, height, depth,
1913 border, format, type, pixels);
1914 }
1915
1916
1917 void GLAPIENTRY
1918 _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
1919 GLsizei width, GLsizei height, GLsizei depth,
1920 GLint border, GLenum format, GLenum type,
1921 const GLvoid *pixels )
1922 {
1923 _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
1924 depth, border, format, type, pixels);
1925 }
1926
1927
1928 /**
1929 * Implement all the glTexSubImage1/2/3D() functions.
1930 */
1931 static void
1932 texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
1933 GLint xoffset, GLint yoffset, GLint zoffset,
1934 GLsizei width, GLsizei height, GLsizei depth,
1935 GLenum format, GLenum type, const GLvoid *pixels )
1936 {
1937 struct gl_texture_object *texObj;
1938 struct gl_texture_image *texImage;
1939
1940 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1941
1942 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
1943 _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
1944 dims,
1945 _mesa_lookup_enum_by_nr(target), level,
1946 xoffset, yoffset, zoffset, width, height, depth,
1947 _mesa_lookup_enum_by_nr(format),
1948 _mesa_lookup_enum_by_nr(type), pixels);
1949
1950 /* check target (proxies not allowed) */
1951 if (!legal_texsubimage_target(ctx, dims, target)) {
1952 _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
1953 dims, _mesa_lookup_enum_by_nr(target));
1954 return;
1955 }
1956
1957 if (ctx->NewState & _NEW_PIXEL)
1958 _mesa_update_state(ctx);
1959
1960 if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset,
1961 width, height, depth, format, type)) {
1962 return; /* error was detected */
1963 }
1964
1965 texObj = _mesa_get_current_tex_object(ctx, target);
1966
1967 _mesa_lock_texture(ctx, texObj);
1968 {
1969 texImage = _mesa_select_tex_image(ctx, texObj, target, level);
1970
1971 if (subtexture_error_check2(ctx, dims, target, level,
1972 xoffset, yoffset, zoffset,
1973 width, height, depth,
1974 format, type, texImage)) {
1975 /* error was recorded */
1976 }
1977 else if (width > 0 && height > 0 && depth > 0) {
1978 /* If we have a border, offset=-1 is legal. Bias by border width. */
1979 switch (dims) {
1980 case 3:
1981 zoffset += texImage->Border;
1982 /* fall-through */
1983 case 2:
1984 yoffset += texImage->Border;
1985 /* fall-through */
1986 case 1:
1987 xoffset += texImage->Border;
1988 }
1989
1990 switch (dims) {
1991 case 1:
1992 ctx->Driver.TexSubImage1D(ctx, texImage,
1993 xoffset, width,
1994 format, type, pixels, &ctx->Unpack);
1995 break;
1996 case 2:
1997 ctx->Driver.TexSubImage2D(ctx, texImage,
1998 xoffset, yoffset, width, height,
1999 format, type, pixels, &ctx->Unpack);
2000 break;
2001 case 3:
2002 ctx->Driver.TexSubImage3D(ctx, texImage,
2003 xoffset, yoffset, zoffset,
2004 width, height, depth,
2005 format, type, pixels, &ctx->Unpack);
2006 break;
2007 default:
2008 _mesa_problem(ctx, "unexpected dims in subteximage()");
2009 }
2010
2011 ctx->NewState |= _NEW_TEXTURE;
2012 }
2013 }
2014 _mesa_unlock_texture(ctx, texObj);
2015 }
2016
2017
2018 void GLAPIENTRY
2019 _mesa_TexSubImage1D( GLenum target, GLint level,
2020 GLint xoffset, GLsizei width,
2021 GLenum format, GLenum type,
2022 const GLvoid *pixels )
2023 {
2024 GET_CURRENT_CONTEXT(ctx);
2025 texsubimage(ctx, 1, target, level,
2026 xoffset, 0, 0,
2027 width, 1, 1,
2028 format, type, pixels);
2029 }
2030
2031
2032 void GLAPIENTRY
2033 _mesa_TexSubImage2D( GLenum target, GLint level,
2034 GLint xoffset, GLint yoffset,
2035 GLsizei width, GLsizei height,
2036 GLenum format, GLenum type,
2037 const GLvoid *pixels )
2038 {
2039 GET_CURRENT_CONTEXT(ctx);
2040 texsubimage(ctx, 2, target, level,
2041 xoffset, yoffset, 0,
2042 width, height, 1,
2043 format, type, pixels);
2044 }
2045
2046
2047
2048 void GLAPIENTRY
2049 _mesa_TexSubImage3D( GLenum target, GLint level,
2050 GLint xoffset, GLint yoffset, GLint zoffset,
2051 GLsizei width, GLsizei height, GLsizei depth,
2052 GLenum format, GLenum type,
2053 const GLvoid *pixels )
2054 {
2055 GET_CURRENT_CONTEXT(ctx);
2056 texsubimage(ctx, 3, target, level,
2057 xoffset, yoffset, zoffset,
2058 width, height, depth,
2059 format, type, pixels);
2060 }
2061
2062
2063
2064 /**
2065 * For glCopyTexSubImage, return the source renderbuffer to copy texel data
2066 * from. This depends on whether the texture contains color or depth values.
2067 */
2068 static struct gl_renderbuffer *
2069 get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat)
2070 {
2071 if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) {
2072 /* reading from depth/stencil buffer */
2073 return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
2074 }
2075 else {
2076 /* copying from color buffer */
2077 return ctx->ReadBuffer->_ColorReadBuffer;
2078 }
2079 }
2080
2081
2082
2083 /**
2084 * Implement the glCopyTexImage1/2D() functions.
2085 */
2086 static void
2087 copyteximage(struct gl_context *ctx, GLuint dims,
2088 GLenum target, GLint level, GLenum internalFormat,
2089 GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
2090 {
2091 struct gl_texture_object *texObj;
2092 struct gl_texture_image *texImage;
2093
2094 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2095
2096 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2097 _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
2098 dims,
2099 _mesa_lookup_enum_by_nr(target), level,
2100 _mesa_lookup_enum_by_nr(internalFormat),
2101 x, y, width, height, border);
2102
2103 if (ctx->NewState & NEW_COPY_TEX_STATE)
2104 _mesa_update_state(ctx);
2105
2106 if (copytexture_error_check(ctx, dims, target, level, internalFormat,
2107 width, height, border))
2108 return;
2109
2110 texObj = _mesa_get_current_tex_object(ctx, target);
2111
2112 if (border && ctx->Const.StripTextureBorder) {
2113 x += border;
2114 width -= border * 2;
2115 if (dims == 2) {
2116 y += border;
2117 height -= border * 2;
2118 }
2119 border = 0;
2120 }
2121
2122 _mesa_lock_texture(ctx, texObj);
2123 {
2124 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
2125
2126 if (!texImage) {
2127 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
2128 }
2129 else {
2130 /* choose actual hw format */
2131 gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
2132 target, level,
2133 internalFormat,
2134 GL_NONE, GL_NONE);
2135
2136 if (legal_texture_size(ctx, texFormat, width, height, 1)) {
2137 GLint srcX = x, srcY = y, dstX = 0, dstY = 0;
2138
2139 /* Free old texture image */
2140 ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
2141
2142 _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
2143 border, internalFormat, texFormat);
2144
2145 /* Allocate texture memory (no pixel data yet) */
2146 if (dims == 1) {
2147 ctx->Driver.TexImage1D(ctx, texImage, internalFormat,
2148 width, border, GL_NONE, GL_NONE, NULL,
2149 &ctx->Unpack);
2150 }
2151 else {
2152 ctx->Driver.TexImage2D(ctx, texImage, internalFormat,
2153 width, height, border, GL_NONE, GL_NONE,
2154 NULL, &ctx->Unpack);
2155 }
2156
2157 if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
2158 &width, &height)) {
2159 struct gl_renderbuffer *srcRb =
2160 get_copy_tex_image_source(ctx, texImage->TexFormat);
2161
2162 if (dims == 1)
2163 ctx->Driver.CopyTexSubImage1D(ctx, texImage, dstX,
2164 srcRb, srcX, srcY, width);
2165
2166 else
2167 ctx->Driver.CopyTexSubImage2D(ctx, texImage, dstX, dstY,
2168 srcRb, srcX, srcY, width, height);
2169 }
2170
2171 /* state update */
2172 texObj->_Complete = GL_FALSE;
2173 ctx->NewState |= _NEW_TEXTURE;
2174 }
2175 else {
2176 /* probably too large of image */
2177 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
2178 }
2179 }
2180 }
2181 _mesa_unlock_texture(ctx, texObj);
2182 }
2183
2184
2185
2186 void GLAPIENTRY
2187 _mesa_CopyTexImage1D( GLenum target, GLint level,
2188 GLenum internalFormat,
2189 GLint x, GLint y,
2190 GLsizei width, GLint border )
2191 {
2192 GET_CURRENT_CONTEXT(ctx);
2193 copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
2194 }
2195
2196
2197
2198 void GLAPIENTRY
2199 _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
2200 GLint x, GLint y, GLsizei width, GLsizei height,
2201 GLint border )
2202 {
2203 GET_CURRENT_CONTEXT(ctx);
2204 copyteximage(ctx, 2, target, level, internalFormat,
2205 x, y, width, height, border);
2206 }
2207
2208
2209
2210 /**
2211 * Implementation for glCopyTexSubImage1/2/3D() functions.
2212 */
2213 static void
2214 copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
2215 GLint xoffset, GLint yoffset, GLint zoffset,
2216 GLint x, GLint y, GLsizei width, GLsizei height)
2217 {
2218 struct gl_texture_object *texObj;
2219 struct gl_texture_image *texImage;
2220
2221 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2222
2223 if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2224 _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n",
2225 dims,
2226 _mesa_lookup_enum_by_nr(target),
2227 level, xoffset, yoffset, zoffset, x, y, width, height);
2228
2229 if (ctx->NewState & NEW_COPY_TEX_STATE)
2230 _mesa_update_state(ctx);
2231
2232 if (copytexsubimage_error_check1(ctx, dims, target, level))
2233 return;
2234
2235 texObj = _mesa_get_current_tex_object(ctx, target);
2236
2237 _mesa_lock_texture(ctx, texObj);
2238 {
2239 texImage = _mesa_select_tex_image(ctx, texObj, target, level);
2240
2241 if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset,
2242 zoffset, width, height, texImage)) {
2243 /* error was recored */
2244 }
2245 else {
2246 /* If we have a border, offset=-1 is legal. Bias by border width. */
2247 switch (dims) {
2248 case 3:
2249 zoffset += texImage->Border;
2250 /* fall-through */
2251 case 2:
2252 yoffset += texImage->Border;
2253 /* fall-through */
2254 case 1:
2255 xoffset += texImage->Border;
2256 }
2257
2258 if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
2259 &width, &height)) {
2260 struct gl_renderbuffer *srcRb =
2261 get_copy_tex_image_source(ctx, texImage->TexFormat);
2262
2263 switch (dims) {
2264 case 1:
2265 ctx->Driver.CopyTexSubImage1D(ctx, texImage, xoffset,
2266 srcRb, x, y, width);
2267 break;
2268 case 2:
2269 ctx->Driver.CopyTexSubImage2D(ctx, texImage, xoffset, yoffset,
2270 srcRb, x, y, width, height);
2271 break;
2272 case 3:
2273 ctx->Driver.CopyTexSubImage3D(ctx, texImage,
2274 xoffset, yoffset, zoffset,
2275 srcRb, x, y, width, height);
2276 break;
2277 default:
2278 _mesa_problem(ctx, "bad dims in copytexsubimage()");
2279 }
2280
2281 ctx->NewState |= _NEW_TEXTURE;
2282 }
2283 }
2284 }
2285 _mesa_unlock_texture(ctx, texObj);
2286 }
2287
2288
2289 void GLAPIENTRY
2290 _mesa_CopyTexSubImage1D( GLenum target, GLint level,
2291 GLint xoffset, GLint x, GLint y, GLsizei width )
2292 {
2293 GET_CURRENT_CONTEXT(ctx);
2294 copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1);
2295 }
2296
2297
2298
2299 void GLAPIENTRY
2300 _mesa_CopyTexSubImage2D( GLenum target, GLint level,
2301 GLint xoffset, GLint yoffset,
2302 GLint x, GLint y, GLsizei width, GLsizei height )
2303 {
2304 GET_CURRENT_CONTEXT(ctx);
2305 copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y,
2306 width, height);
2307 }
2308
2309
2310
2311 void GLAPIENTRY
2312 _mesa_CopyTexSubImage3D( GLenum target, GLint level,
2313 GLint xoffset, GLint yoffset, GLint zoffset,
2314 GLint x, GLint y, GLsizei width, GLsizei height )
2315 {
2316 GET_CURRENT_CONTEXT(ctx);
2317 copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
2318 x, y, width, height);
2319 }