teximage.c revision efa6b5e42b427c1ec9f2d636d280c84e7da71346
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#include <stdbool.h>
32#include "glheader.h"
33#include "bufferobj.h"
34#include "context.h"
35#include "enums.h"
36#include "fbobject.h"
37#include "framebuffer.h"
38#include "hash.h"
39#include "image.h"
40#include "imports.h"
41#include "macros.h"
42#include "mfeatures.h"
43#include "state.h"
44#include "texcompress.h"
45#include "texcompress_cpal.h"
46#include "teximage.h"
47#include "texobj.h"
48#include "texstate.h"
49#include "mtypes.h"
50#include "glformats.h"
51
52
53/* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT.
54 */
55#ifndef GL_HALF_FLOAT_OES
56#define GL_HALF_FLOAT_OES 0x8D61
57#endif
58
59/**
60 * State changes which we care about for glCopyTex[Sub]Image() calls.
61 * In particular, we care about pixel transfer state and buffer state
62 * (such as glReadBuffer to make sure we read from the right renderbuffer).
63 */
64#define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL)
65
66
67
68/**
69 * Return the simple base format for a given internal texture format.
70 * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
71 *
72 * \param ctx GL context.
73 * \param internalFormat the internal texture format token or 1, 2, 3, or 4.
74 *
75 * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
76 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
77 *
78 * This is the format which is used during texture application (i.e. the
79 * texture format and env mode determine the arithmetic used.
80 */
81GLint
82_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
83{
84   switch (internalFormat) {
85      case GL_ALPHA:
86      case GL_ALPHA4:
87      case GL_ALPHA8:
88      case GL_ALPHA12:
89      case GL_ALPHA16:
90         return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1;
91      case 1:
92      case GL_LUMINANCE:
93      case GL_LUMINANCE4:
94      case GL_LUMINANCE8:
95      case GL_LUMINANCE12:
96      case GL_LUMINANCE16:
97         return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1;
98      case 2:
99      case GL_LUMINANCE_ALPHA:
100      case GL_LUMINANCE4_ALPHA4:
101      case GL_LUMINANCE6_ALPHA2:
102      case GL_LUMINANCE8_ALPHA8:
103      case GL_LUMINANCE12_ALPHA4:
104      case GL_LUMINANCE12_ALPHA12:
105      case GL_LUMINANCE16_ALPHA16:
106         return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1;
107      case GL_INTENSITY:
108      case GL_INTENSITY4:
109      case GL_INTENSITY8:
110      case GL_INTENSITY12:
111      case GL_INTENSITY16:
112         return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1;
113      case 3:
114         return (ctx->API != API_OPENGL_CORE) ? GL_RGB : -1;
115      case GL_RGB:
116      case GL_R3_G3_B2:
117      case GL_RGB4:
118      case GL_RGB5:
119      case GL_RGB8:
120      case GL_RGB10:
121      case GL_RGB12:
122      case GL_RGB16:
123         return GL_RGB;
124      case 4:
125         return (ctx->API != API_OPENGL_CORE) ? GL_RGBA : -1;
126      case GL_RGBA:
127      case GL_RGBA2:
128      case GL_RGBA4:
129      case GL_RGB5_A1:
130      case GL_RGBA8:
131      case GL_RGB10_A2:
132      case GL_RGBA12:
133      case GL_RGBA16:
134         return GL_RGBA;
135      default:
136         ; /* fallthrough */
137   }
138
139   /* GL_BGRA can be an internal format *only* in OpenGL ES (1.x or 2.0).
140    */
141   if (_mesa_is_gles(ctx)) {
142      switch (internalFormat) {
143         case GL_BGRA:
144            return GL_RGBA;
145         default:
146            ; /* fallthrough */
147      }
148   }
149
150   if (ctx->Extensions.ARB_ES2_compatibility) {
151      switch (internalFormat) {
152         case GL_RGB565:
153            return GL_RGB;
154         default:
155            ; /* fallthrough */
156      }
157   }
158
159   if (ctx->Extensions.ARB_depth_texture) {
160      switch (internalFormat) {
161         case GL_DEPTH_COMPONENT:
162         case GL_DEPTH_COMPONENT16:
163         case GL_DEPTH_COMPONENT24:
164         case GL_DEPTH_COMPONENT32:
165            return GL_DEPTH_COMPONENT;
166         default:
167            ; /* fallthrough */
168      }
169   }
170
171   switch (internalFormat) {
172   case GL_COMPRESSED_ALPHA:
173      return GL_ALPHA;
174   case GL_COMPRESSED_LUMINANCE:
175      return GL_LUMINANCE;
176   case GL_COMPRESSED_LUMINANCE_ALPHA:
177      return GL_LUMINANCE_ALPHA;
178   case GL_COMPRESSED_INTENSITY:
179      return GL_INTENSITY;
180   case GL_COMPRESSED_RGB:
181      return GL_RGB;
182   case GL_COMPRESSED_RGBA:
183      return GL_RGBA;
184   default:
185      ; /* fallthrough */
186   }
187
188   if (ctx->Extensions.TDFX_texture_compression_FXT1) {
189      switch (internalFormat) {
190         case GL_COMPRESSED_RGB_FXT1_3DFX:
191            return GL_RGB;
192         case GL_COMPRESSED_RGBA_FXT1_3DFX:
193            return GL_RGBA;
194         default:
195            ; /* fallthrough */
196      }
197   }
198
199   if (ctx->Extensions.EXT_texture_compression_s3tc) {
200      switch (internalFormat) {
201         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
202            return GL_RGB;
203         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
204         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
205         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
206            return GL_RGBA;
207         default:
208            ; /* fallthrough */
209      }
210   }
211
212   if (ctx->Extensions.S3_s3tc) {
213      switch (internalFormat) {
214         case GL_RGB_S3TC:
215         case GL_RGB4_S3TC:
216            return GL_RGB;
217         case GL_RGBA_S3TC:
218         case GL_RGBA4_S3TC:
219            return GL_RGBA;
220         default:
221            ; /* fallthrough */
222      }
223   }
224
225   if (ctx->Extensions.MESA_ycbcr_texture) {
226      if (internalFormat == GL_YCBCR_MESA)
227         return GL_YCBCR_MESA;
228   }
229
230   if (ctx->Extensions.ARB_texture_float) {
231      switch (internalFormat) {
232         case GL_ALPHA16F_ARB:
233         case GL_ALPHA32F_ARB:
234            return GL_ALPHA;
235         case GL_RGBA16F_ARB:
236         case GL_RGBA32F_ARB:
237            return GL_RGBA;
238         case GL_RGB16F_ARB:
239         case GL_RGB32F_ARB:
240            return GL_RGB;
241         case GL_INTENSITY16F_ARB:
242         case GL_INTENSITY32F_ARB:
243            return GL_INTENSITY;
244         case GL_LUMINANCE16F_ARB:
245         case GL_LUMINANCE32F_ARB:
246            return GL_LUMINANCE;
247         case GL_LUMINANCE_ALPHA16F_ARB:
248         case GL_LUMINANCE_ALPHA32F_ARB:
249            return GL_LUMINANCE_ALPHA;
250         default:
251            ; /* fallthrough */
252      }
253   }
254
255   if (ctx->Extensions.ATI_envmap_bumpmap) {
256      switch (internalFormat) {
257         case GL_DUDV_ATI:
258         case GL_DU8DV8_ATI:
259            return GL_DUDV_ATI;
260         default:
261            ; /* fallthrough */
262      }
263   }
264
265   if (ctx->Extensions.EXT_texture_snorm) {
266      switch (internalFormat) {
267         case GL_RED_SNORM:
268         case GL_R8_SNORM:
269         case GL_R16_SNORM:
270            return GL_RED;
271         case GL_RG_SNORM:
272         case GL_RG8_SNORM:
273         case GL_RG16_SNORM:
274            return GL_RG;
275         case GL_RGB_SNORM:
276         case GL_RGB8_SNORM:
277         case GL_RGB16_SNORM:
278            return GL_RGB;
279         case GL_RGBA_SNORM:
280         case GL_RGBA8_SNORM:
281         case GL_RGBA16_SNORM:
282            return GL_RGBA;
283         case GL_ALPHA_SNORM:
284         case GL_ALPHA8_SNORM:
285         case GL_ALPHA16_SNORM:
286            return GL_ALPHA;
287         case GL_LUMINANCE_SNORM:
288         case GL_LUMINANCE8_SNORM:
289         case GL_LUMINANCE16_SNORM:
290            return GL_LUMINANCE;
291         case GL_LUMINANCE_ALPHA_SNORM:
292         case GL_LUMINANCE8_ALPHA8_SNORM:
293         case GL_LUMINANCE16_ALPHA16_SNORM:
294            return GL_LUMINANCE_ALPHA;
295         case GL_INTENSITY_SNORM:
296         case GL_INTENSITY8_SNORM:
297         case GL_INTENSITY16_SNORM:
298            return GL_INTENSITY;
299         default:
300            ; /* fallthrough */
301      }
302   }
303
304   if (ctx->Extensions.EXT_packed_depth_stencil) {
305      switch (internalFormat) {
306         case GL_DEPTH_STENCIL_EXT:
307         case GL_DEPTH24_STENCIL8_EXT:
308            return GL_DEPTH_STENCIL_EXT;
309         default:
310            ; /* fallthrough */
311      }
312   }
313
314#if FEATURE_EXT_texture_sRGB
315   if (ctx->Extensions.EXT_texture_sRGB) {
316      switch (internalFormat) {
317      case GL_SRGB_EXT:
318      case GL_SRGB8_EXT:
319      case GL_COMPRESSED_SRGB_EXT:
320      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
321         return GL_RGB;
322      case GL_SRGB_ALPHA_EXT:
323      case GL_SRGB8_ALPHA8_EXT:
324      case GL_COMPRESSED_SRGB_ALPHA_EXT:
325      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
326      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
327      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
328         return GL_RGBA;
329      case GL_SLUMINANCE_ALPHA_EXT:
330      case GL_SLUMINANCE8_ALPHA8_EXT:
331      case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
332         return GL_LUMINANCE_ALPHA;
333      case GL_SLUMINANCE_EXT:
334      case GL_SLUMINANCE8_EXT:
335      case GL_COMPRESSED_SLUMINANCE_EXT:
336         return GL_LUMINANCE;
337      default:
338         ; /* fallthrough */
339      }
340   }
341#endif /* FEATURE_EXT_texture_sRGB */
342
343   if (ctx->Version >= 30 ||
344       ctx->Extensions.EXT_texture_integer) {
345      switch (internalFormat) {
346      case GL_RGBA8UI_EXT:
347      case GL_RGBA16UI_EXT:
348      case GL_RGBA32UI_EXT:
349      case GL_RGBA8I_EXT:
350      case GL_RGBA16I_EXT:
351      case GL_RGBA32I_EXT:
352      case GL_RGB10_A2UI:
353         return GL_RGBA;
354      case GL_RGB8UI_EXT:
355      case GL_RGB16UI_EXT:
356      case GL_RGB32UI_EXT:
357      case GL_RGB8I_EXT:
358      case GL_RGB16I_EXT:
359      case GL_RGB32I_EXT:
360         return GL_RGB;
361      }
362   }
363
364   if (ctx->Extensions.EXT_texture_integer) {
365      switch (internalFormat) {
366      case GL_ALPHA8UI_EXT:
367      case GL_ALPHA16UI_EXT:
368      case GL_ALPHA32UI_EXT:
369      case GL_ALPHA8I_EXT:
370      case GL_ALPHA16I_EXT:
371      case GL_ALPHA32I_EXT:
372         return GL_ALPHA;
373      case GL_INTENSITY8UI_EXT:
374      case GL_INTENSITY16UI_EXT:
375      case GL_INTENSITY32UI_EXT:
376      case GL_INTENSITY8I_EXT:
377      case GL_INTENSITY16I_EXT:
378      case GL_INTENSITY32I_EXT:
379         return GL_INTENSITY;
380      case GL_LUMINANCE8UI_EXT:
381      case GL_LUMINANCE16UI_EXT:
382      case GL_LUMINANCE32UI_EXT:
383      case GL_LUMINANCE8I_EXT:
384      case GL_LUMINANCE16I_EXT:
385      case GL_LUMINANCE32I_EXT:
386         return GL_LUMINANCE;
387      case GL_LUMINANCE_ALPHA8UI_EXT:
388      case GL_LUMINANCE_ALPHA16UI_EXT:
389      case GL_LUMINANCE_ALPHA32UI_EXT:
390      case GL_LUMINANCE_ALPHA8I_EXT:
391      case GL_LUMINANCE_ALPHA16I_EXT:
392      case GL_LUMINANCE_ALPHA32I_EXT:
393         return GL_LUMINANCE_ALPHA;
394      default:
395         ; /* fallthrough */
396      }
397   }
398
399   if (ctx->Extensions.ARB_texture_rg) {
400      switch (internalFormat) {
401      case GL_R16F:
402	 /* R16F depends on both ARB_half_float_pixel and ARB_texture_float.
403	  */
404	 if (!ctx->Extensions.ARB_half_float_pixel)
405	    break;
406	 /* FALLTHROUGH */
407      case GL_R32F:
408	 if (!ctx->Extensions.ARB_texture_float)
409	    break;
410         return GL_RED;
411      case GL_R8I:
412      case GL_R8UI:
413      case GL_R16I:
414      case GL_R16UI:
415      case GL_R32I:
416      case GL_R32UI:
417	 if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer)
418	    break;
419	 /* FALLTHROUGH */
420      case GL_R8:
421      case GL_R16:
422      case GL_RED:
423      case GL_COMPRESSED_RED:
424         return GL_RED;
425
426      case GL_RG16F:
427	 /* RG16F depends on both ARB_half_float_pixel and ARB_texture_float.
428	  */
429	 if (!ctx->Extensions.ARB_half_float_pixel)
430	    break;
431	 /* FALLTHROUGH */
432      case GL_RG32F:
433	 if (!ctx->Extensions.ARB_texture_float)
434	    break;
435         return GL_RG;
436      case GL_RG8I:
437      case GL_RG8UI:
438      case GL_RG16I:
439      case GL_RG16UI:
440      case GL_RG32I:
441      case GL_RG32UI:
442	 if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer)
443	    break;
444	 /* FALLTHROUGH */
445      case GL_RG:
446      case GL_RG8:
447      case GL_RG16:
448      case GL_COMPRESSED_RG:
449         return GL_RG;
450      default:
451         ; /* fallthrough */
452      }
453   }
454
455   if (ctx->Extensions.EXT_texture_shared_exponent) {
456      switch (internalFormat) {
457      case GL_RGB9_E5_EXT:
458         return GL_RGB;
459      default:
460         ; /* fallthrough */
461      }
462   }
463
464   if (ctx->Extensions.EXT_packed_float) {
465      switch (internalFormat) {
466      case GL_R11F_G11F_B10F_EXT:
467         return GL_RGB;
468      default:
469         ; /* fallthrough */
470      }
471   }
472
473   if (ctx->Extensions.ARB_depth_buffer_float) {
474      switch (internalFormat) {
475      case GL_DEPTH_COMPONENT32F:
476         return GL_DEPTH_COMPONENT;
477      case GL_DEPTH32F_STENCIL8:
478         return GL_DEPTH_STENCIL;
479      default:
480         ; /* fallthrough */
481      }
482   }
483
484   if (ctx->Extensions.ARB_texture_compression_rgtc) {
485      switch (internalFormat) {
486      case GL_COMPRESSED_RED_RGTC1:
487      case GL_COMPRESSED_SIGNED_RED_RGTC1:
488         return GL_RED;
489      case GL_COMPRESSED_RG_RGTC2:
490      case GL_COMPRESSED_SIGNED_RG_RGTC2:
491         return GL_RG;
492      default:
493         ; /* fallthrough */
494      }
495   }
496
497   if (ctx->Extensions.EXT_texture_compression_latc) {
498      switch (internalFormat) {
499      case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
500      case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
501         return GL_LUMINANCE;
502      case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
503      case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
504         return GL_LUMINANCE_ALPHA;
505      default:
506         ; /* fallthrough */
507      }
508   }
509
510   if (ctx->Extensions.ATI_texture_compression_3dc) {
511      switch (internalFormat) {
512      case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
513         return GL_LUMINANCE_ALPHA;
514      default:
515         ; /* fallthrough */
516      }
517   }
518
519   if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) {
520      switch (internalFormat) {
521      case GL_ETC1_RGB8_OES:
522         return GL_RGB;
523      default:
524         ; /* fallthrough */
525      }
526   }
527
528   if (ctx->API == API_OPENGLES) {
529      switch (internalFormat) {
530      case GL_PALETTE4_RGB8_OES:
531      case GL_PALETTE4_R5_G6_B5_OES:
532      case GL_PALETTE8_RGB8_OES:
533      case GL_PALETTE8_R5_G6_B5_OES:
534	 return GL_RGB;
535      case GL_PALETTE4_RGBA8_OES:
536      case GL_PALETTE8_RGB5_A1_OES:
537      case GL_PALETTE4_RGBA4_OES:
538      case GL_PALETTE4_RGB5_A1_OES:
539      case GL_PALETTE8_RGBA8_OES:
540      case GL_PALETTE8_RGBA4_OES:
541	 return GL_RGBA;
542      default:
543         ; /* fallthrough */
544      }
545   }
546
547   return -1; /* error */
548}
549
550
551/**
552 * For cube map faces, return a face index in [0,5].
553 * For other targets return 0;
554 */
555GLuint
556_mesa_tex_target_to_face(GLenum target)
557{
558   if (_mesa_is_cube_face(target))
559      return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
560   else
561      return 0;
562}
563
564
565
566/**
567 * Install gl_texture_image in a gl_texture_object according to the target
568 * and level parameters.
569 *
570 * \param tObj texture object.
571 * \param target texture target.
572 * \param level image level.
573 * \param texImage texture image.
574 */
575static void
576set_tex_image(struct gl_texture_object *tObj,
577              GLenum target, GLint level,
578              struct gl_texture_image *texImage)
579{
580   const GLuint face = _mesa_tex_target_to_face(target);
581
582   ASSERT(tObj);
583   ASSERT(texImage);
584   if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES)
585      assert(level == 0);
586
587   tObj->Image[face][level] = texImage;
588
589   /* Set the 'back' pointer */
590   texImage->TexObject = tObj;
591   texImage->Level = level;
592   texImage->Face = face;
593}
594
595
596/**
597 * Allocate a texture image structure.
598 *
599 * Called via ctx->Driver.NewTextureImage() unless overriden by a device
600 * driver.
601 *
602 * \return a pointer to gl_texture_image struct with all fields initialized to
603 * zero.
604 */
605struct gl_texture_image *
606_mesa_new_texture_image( struct gl_context *ctx )
607{
608   (void) ctx;
609   return CALLOC_STRUCT(gl_texture_image);
610}
611
612
613/**
614 * Free a gl_texture_image and associated data.
615 * This function is a fallback called via ctx->Driver.DeleteTextureImage().
616 *
617 * \param texImage texture image.
618 *
619 * Free the texture image structure and the associated image data.
620 */
621void
622_mesa_delete_texture_image(struct gl_context *ctx,
623                           struct gl_texture_image *texImage)
624{
625   /* Free texImage->Data and/or any other driver-specific texture
626    * image storage.
627    */
628   ASSERT(ctx->Driver.FreeTextureImageBuffer);
629   ctx->Driver.FreeTextureImageBuffer( ctx, texImage );
630   free(texImage);
631}
632
633
634/**
635 * Test if a target is a proxy target.
636 *
637 * \param target texture target.
638 *
639 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
640 */
641GLboolean
642_mesa_is_proxy_texture(GLenum target)
643{
644   /*
645    * NUM_TEXTURE_TARGETS should match number of terms below, except there's no
646    * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
647    */
648   assert(NUM_TEXTURE_TARGETS == 7 + 2);
649
650   return (target == GL_PROXY_TEXTURE_1D ||
651           target == GL_PROXY_TEXTURE_2D ||
652           target == GL_PROXY_TEXTURE_3D ||
653           target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
654           target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
655           target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
656           target == GL_PROXY_TEXTURE_2D_ARRAY_EXT);
657}
658
659
660/**
661 * Return the proxy target which corresponds to the given texture target
662 */
663GLenum
664_mesa_get_proxy_target(GLenum target)
665{
666   switch (target) {
667   case GL_TEXTURE_1D:
668   case GL_PROXY_TEXTURE_1D:
669      return GL_PROXY_TEXTURE_1D;
670   case GL_TEXTURE_2D:
671   case GL_PROXY_TEXTURE_2D:
672      return GL_PROXY_TEXTURE_2D;
673   case GL_TEXTURE_3D:
674   case GL_PROXY_TEXTURE_3D:
675      return GL_PROXY_TEXTURE_3D;
676   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
677   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
678   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
679   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
680   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
681   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
682   case GL_TEXTURE_CUBE_MAP_ARB:
683   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
684      return GL_PROXY_TEXTURE_CUBE_MAP_ARB;
685   case GL_TEXTURE_RECTANGLE_NV:
686   case GL_PROXY_TEXTURE_RECTANGLE_NV:
687      return GL_PROXY_TEXTURE_RECTANGLE_NV;
688   case GL_TEXTURE_1D_ARRAY_EXT:
689   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
690      return GL_PROXY_TEXTURE_1D_ARRAY_EXT;
691   case GL_TEXTURE_2D_ARRAY_EXT:
692   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
693      return GL_PROXY_TEXTURE_2D_ARRAY_EXT;
694   default:
695      _mesa_problem(NULL, "unexpected target in _mesa_get_proxy_target()");
696      return 0;
697   }
698}
699
700
701/**
702 * Get the texture object that corresponds to the target of the given
703 * texture unit.  The target should have already been checked for validity.
704 *
705 * \param ctx GL context.
706 * \param texUnit texture unit.
707 * \param target texture target.
708 *
709 * \return pointer to the texture object on success, or NULL on failure.
710 */
711struct gl_texture_object *
712_mesa_select_tex_object(struct gl_context *ctx,
713                        const struct gl_texture_unit *texUnit,
714                        GLenum target)
715{
716   const GLboolean arrayTex = (ctx->Extensions.MESA_texture_array ||
717                               ctx->Extensions.EXT_texture_array);
718
719   switch (target) {
720      case GL_TEXTURE_1D:
721         return texUnit->CurrentTex[TEXTURE_1D_INDEX];
722      case GL_PROXY_TEXTURE_1D:
723         return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
724      case GL_TEXTURE_2D:
725         return texUnit->CurrentTex[TEXTURE_2D_INDEX];
726      case GL_PROXY_TEXTURE_2D:
727         return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
728      case GL_TEXTURE_3D:
729         return texUnit->CurrentTex[TEXTURE_3D_INDEX];
730      case GL_PROXY_TEXTURE_3D:
731         return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
732      case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
733      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
734      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
735      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
736      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
737      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
738      case GL_TEXTURE_CUBE_MAP_ARB:
739         return ctx->Extensions.ARB_texture_cube_map
740                ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL;
741      case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
742         return ctx->Extensions.ARB_texture_cube_map
743                ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
744      case GL_TEXTURE_RECTANGLE_NV:
745         return ctx->Extensions.NV_texture_rectangle
746                ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL;
747      case GL_PROXY_TEXTURE_RECTANGLE_NV:
748         return ctx->Extensions.NV_texture_rectangle
749                ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
750      case GL_TEXTURE_1D_ARRAY_EXT:
751         return arrayTex ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
752      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
753         return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
754      case GL_TEXTURE_2D_ARRAY_EXT:
755         return arrayTex ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
756      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
757         return arrayTex ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
758      case GL_TEXTURE_BUFFER:
759         return _mesa_is_desktop_gl(ctx)
760            && ctx->Extensions.ARB_texture_buffer_object
761            ? texUnit->CurrentTex[TEXTURE_BUFFER_INDEX] : NULL;
762      case GL_TEXTURE_EXTERNAL_OES:
763         return ctx->Extensions.OES_EGL_image_external
764            ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL;
765      default:
766         _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
767         return NULL;
768   }
769}
770
771
772/**
773 * Return pointer to texture object for given target on current texture unit.
774 */
775struct gl_texture_object *
776_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target)
777{
778   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
779   return _mesa_select_tex_object(ctx, texUnit, target);
780}
781
782
783/**
784 * Get a texture image pointer from a texture object, given a texture
785 * target and mipmap level.  The target and level parameters should
786 * have already been error-checked.
787 *
788 * \param ctx GL context.
789 * \param texObj texture unit.
790 * \param target texture target.
791 * \param level image level.
792 *
793 * \return pointer to the texture image structure, or NULL on failure.
794 */
795struct gl_texture_image *
796_mesa_select_tex_image(struct gl_context *ctx,
797                       const struct gl_texture_object *texObj,
798		       GLenum target, GLint level)
799{
800   const GLuint face = _mesa_tex_target_to_face(target);
801
802   ASSERT(texObj);
803   ASSERT(level >= 0);
804   ASSERT(level < MAX_TEXTURE_LEVELS);
805
806   return texObj->Image[face][level];
807}
808
809
810/**
811 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
812 * it and install it.  Only return NULL if passed a bad parameter or run
813 * out of memory.
814 */
815struct gl_texture_image *
816_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
817                    GLenum target, GLint level)
818{
819   struct gl_texture_image *texImage;
820
821   if (!texObj)
822      return NULL;
823
824   texImage = _mesa_select_tex_image(ctx, texObj, target, level);
825   if (!texImage) {
826      texImage = ctx->Driver.NewTextureImage(ctx);
827      if (!texImage) {
828         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
829         return NULL;
830      }
831
832      set_tex_image(texObj, target, level, texImage);
833   }
834
835   return texImage;
836}
837
838
839/**
840 * Return pointer to the specified proxy texture image.
841 * Note that proxy textures are per-context, not per-texture unit.
842 * \return pointer to texture image or NULL if invalid target, invalid
843 *         level, or out of memory.
844 */
845static struct gl_texture_image *
846get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
847{
848   struct gl_texture_image *texImage;
849   GLuint texIndex;
850
851   if (level < 0)
852      return NULL;
853
854   switch (target) {
855   case GL_PROXY_TEXTURE_1D:
856      if (level >= ctx->Const.MaxTextureLevels)
857         return NULL;
858      texIndex = TEXTURE_1D_INDEX;
859      break;
860   case GL_PROXY_TEXTURE_2D:
861      if (level >= ctx->Const.MaxTextureLevels)
862         return NULL;
863      texIndex = TEXTURE_2D_INDEX;
864      break;
865   case GL_PROXY_TEXTURE_3D:
866      if (level >= ctx->Const.Max3DTextureLevels)
867         return NULL;
868      texIndex = TEXTURE_3D_INDEX;
869      break;
870   case GL_PROXY_TEXTURE_CUBE_MAP:
871      if (level >= ctx->Const.MaxCubeTextureLevels)
872         return NULL;
873      texIndex = TEXTURE_CUBE_INDEX;
874      break;
875   case GL_PROXY_TEXTURE_RECTANGLE_NV:
876      if (level > 0)
877         return NULL;
878      texIndex = TEXTURE_RECT_INDEX;
879      break;
880   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
881      if (level >= ctx->Const.MaxTextureLevels)
882         return NULL;
883      texIndex = TEXTURE_1D_ARRAY_INDEX;
884      break;
885   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
886      if (level >= ctx->Const.MaxTextureLevels)
887         return NULL;
888      texIndex = TEXTURE_2D_ARRAY_INDEX;
889      break;
890   default:
891      return NULL;
892   }
893
894   texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level];
895   if (!texImage) {
896      texImage = ctx->Driver.NewTextureImage(ctx);
897      if (!texImage) {
898         _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
899         return NULL;
900      }
901      ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage;
902      /* Set the 'back' pointer */
903      texImage->TexObject = ctx->Texture.ProxyTex[texIndex];
904   }
905   return texImage;
906}
907
908
909/**
910 * Get the maximum number of allowed mipmap levels.
911 *
912 * \param ctx GL context.
913 * \param target texture target.
914 *
915 * \return the maximum number of allowed mipmap levels for the given
916 * texture target, or zero if passed a bad target.
917 *
918 * \sa gl_constants.
919 */
920GLint
921_mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
922{
923   switch (target) {
924   case GL_TEXTURE_1D:
925   case GL_PROXY_TEXTURE_1D:
926   case GL_TEXTURE_2D:
927   case GL_PROXY_TEXTURE_2D:
928      return ctx->Const.MaxTextureLevels;
929   case GL_TEXTURE_3D:
930   case GL_PROXY_TEXTURE_3D:
931      return ctx->Const.Max3DTextureLevels;
932   case GL_TEXTURE_CUBE_MAP:
933   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
934   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
935   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
936   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
937   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
938   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
939   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
940      return ctx->Extensions.ARB_texture_cube_map
941         ? ctx->Const.MaxCubeTextureLevels : 0;
942   case GL_TEXTURE_RECTANGLE_NV:
943   case GL_PROXY_TEXTURE_RECTANGLE_NV:
944      return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
945   case GL_TEXTURE_1D_ARRAY_EXT:
946   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
947   case GL_TEXTURE_2D_ARRAY_EXT:
948   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
949      return (ctx->Extensions.MESA_texture_array ||
950              ctx->Extensions.EXT_texture_array)
951         ? ctx->Const.MaxTextureLevels : 0;
952   case GL_TEXTURE_BUFFER:
953      return _mesa_is_desktop_gl(ctx)
954         && ctx->Extensions.ARB_texture_buffer_object
955         ? 1 : 0;
956   case GL_TEXTURE_EXTERNAL_OES:
957      /* fall-through */
958   default:
959      return 0; /* bad target */
960   }
961}
962
963
964/**
965 * Return number of dimensions per mipmap level for the given texture target.
966 */
967GLint
968_mesa_get_texture_dimensions(GLenum target)
969{
970   switch (target) {
971   case GL_TEXTURE_1D:
972   case GL_PROXY_TEXTURE_1D:
973      return 1;
974   case GL_TEXTURE_2D:
975   case GL_TEXTURE_RECTANGLE:
976   case GL_TEXTURE_CUBE_MAP:
977   case GL_PROXY_TEXTURE_2D:
978   case GL_PROXY_TEXTURE_RECTANGLE:
979   case GL_PROXY_TEXTURE_CUBE_MAP:
980   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
981   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
982   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
983   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
984   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
985   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
986   case GL_TEXTURE_1D_ARRAY:
987   case GL_PROXY_TEXTURE_1D_ARRAY:
988   case GL_TEXTURE_EXTERNAL_OES:
989      return 2;
990   case GL_TEXTURE_3D:
991   case GL_PROXY_TEXTURE_3D:
992   case GL_TEXTURE_2D_ARRAY:
993   case GL_PROXY_TEXTURE_2D_ARRAY:
994      return 3;
995   case GL_TEXTURE_BUFFER:
996      /* fall-through */
997   default:
998      _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
999                    target);
1000      return 2;
1001   }
1002}
1003
1004
1005/**
1006 * Return the maximum number of mipmap levels for the given target
1007 * and the dimensions.
1008 * The dimensions are expected not to include the border.
1009 */
1010GLsizei
1011_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height,
1012                             GLsizei depth)
1013{
1014   GLsizei size;
1015
1016   switch (target) {
1017   case GL_TEXTURE_1D:
1018   case GL_TEXTURE_1D_ARRAY:
1019      size = width;
1020      break;
1021   case GL_TEXTURE_CUBE_MAP:
1022   case GL_TEXTURE_CUBE_MAP_ARRAY:
1023      ASSERT(width == height);
1024      size = width;
1025      break;
1026   case GL_TEXTURE_2D:
1027   case GL_TEXTURE_2D_ARRAY:
1028      size = MAX2(width, height);
1029      break;
1030   case GL_TEXTURE_3D:
1031      size = MAX3(width, height, depth);
1032      break;
1033   case GL_TEXTURE_RECTANGLE:
1034      return 1;
1035   default:
1036      assert(0);
1037      return 1;
1038   }
1039
1040   return _mesa_logbase2(size) + 1;
1041}
1042
1043
1044#if 000 /* not used anymore */
1045/*
1046 * glTexImage[123]D can accept a NULL image pointer.  In this case we
1047 * create a texture image with unspecified image contents per the OpenGL
1048 * spec.
1049 */
1050static GLubyte *
1051make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
1052{
1053   const GLint components = _mesa_components_in_format(format);
1054   const GLint numPixels = width * height * depth;
1055   GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
1056
1057#ifdef DEBUG
1058   /*
1059    * Let's see if anyone finds this.  If glTexImage2D() is called with
1060    * a NULL image pointer then load the texture image with something
1061    * interesting instead of leaving it indeterminate.
1062    */
1063   if (data) {
1064      static const char message[8][32] = {
1065         "   X   X  XXXXX   XXX     X    ",
1066         "   XX XX  X      X   X   X X   ",
1067         "   X X X  X      X      X   X  ",
1068         "   X   X  XXXX    XXX   XXXXX  ",
1069         "   X   X  X          X  X   X  ",
1070         "   X   X  X      X   X  X   X  ",
1071         "   X   X  XXXXX   XXX   X   X  ",
1072         "                               "
1073      };
1074
1075      GLubyte *imgPtr = data;
1076      GLint h, i, j, k;
1077      for (h = 0; h < depth; h++) {
1078         for (i = 0; i < height; i++) {
1079            GLint srcRow = 7 - (i % 8);
1080            for (j = 0; j < width; j++) {
1081               GLint srcCol = j % 32;
1082               GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
1083               for (k = 0; k < components; k++) {
1084                  *imgPtr++ = texel;
1085               }
1086            }
1087         }
1088      }
1089   }
1090#endif
1091
1092   return data;
1093}
1094#endif
1095
1096
1097
1098/**
1099 * Set the size and format-related fields of a gl_texture_image struct
1100 * to zero.  This is used when a proxy texture test fails.
1101 */
1102static void
1103clear_teximage_fields(struct gl_texture_image *img)
1104{
1105   ASSERT(img);
1106   img->_BaseFormat = 0;
1107   img->InternalFormat = 0;
1108   img->Border = 0;
1109   img->Width = 0;
1110   img->Height = 0;
1111   img->Depth = 0;
1112   img->Width2 = 0;
1113   img->Height2 = 0;
1114   img->Depth2 = 0;
1115   img->WidthLog2 = 0;
1116   img->HeightLog2 = 0;
1117   img->DepthLog2 = 0;
1118   img->TexFormat = MESA_FORMAT_NONE;
1119}
1120
1121
1122/**
1123 * Initialize basic fields of the gl_texture_image struct.
1124 *
1125 * \param ctx GL context.
1126 * \param img texture image structure to be initialized.
1127 * \param width image width.
1128 * \param height image height.
1129 * \param depth image depth.
1130 * \param border image border.
1131 * \param internalFormat internal format.
1132 * \param format  the actual hardware format (one of MESA_FORMAT_*)
1133 *
1134 * Fills in the fields of \p img with the given information.
1135 * Note: width, height and depth include the border.
1136 */
1137void
1138_mesa_init_teximage_fields(struct gl_context *ctx,
1139                           struct gl_texture_image *img,
1140                           GLsizei width, GLsizei height, GLsizei depth,
1141                           GLint border, GLenum internalFormat,
1142                           gl_format format)
1143{
1144   GLenum target;
1145   ASSERT(img);
1146   ASSERT(width >= 0);
1147   ASSERT(height >= 0);
1148   ASSERT(depth >= 0);
1149
1150   target = img->TexObject->Target;
1151   img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
1152   ASSERT(img->_BaseFormat > 0);
1153   img->InternalFormat = internalFormat;
1154   img->Border = border;
1155   img->Width = width;
1156   img->Height = height;
1157   img->Depth = depth;
1158
1159   img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
1160   img->WidthLog2 = _mesa_logbase2(img->Width2);
1161
1162   switch(target) {
1163   case GL_TEXTURE_1D:
1164   case GL_TEXTURE_BUFFER:
1165   case GL_PROXY_TEXTURE_1D:
1166      if (height == 0)
1167         img->Height2 = 0;
1168      else
1169         img->Height2 = 1;
1170      img->HeightLog2 = 0;
1171      if (depth == 0)
1172         img->Depth2 = 0;
1173      else
1174         img->Depth2 = 1;
1175      img->DepthLog2 = 0;
1176      break;
1177   case GL_TEXTURE_1D_ARRAY:
1178   case GL_PROXY_TEXTURE_1D_ARRAY:
1179      img->Height2 = height; /* no border */
1180      img->HeightLog2 = 0; /* not used */
1181      if (depth == 0)
1182         img->Depth2 = 0;
1183      else
1184         img->Depth2 = 1;
1185      img->DepthLog2 = 0;
1186      break;
1187   case GL_TEXTURE_2D:
1188   case GL_TEXTURE_RECTANGLE:
1189   case GL_TEXTURE_CUBE_MAP:
1190   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1191   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1192   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1193   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1194   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1195   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1196   case GL_TEXTURE_EXTERNAL_OES:
1197   case GL_PROXY_TEXTURE_2D:
1198   case GL_PROXY_TEXTURE_RECTANGLE:
1199   case GL_PROXY_TEXTURE_CUBE_MAP:
1200      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
1201      img->HeightLog2 = _mesa_logbase2(img->Height2);
1202      if (depth == 0)
1203         img->Depth2 = 0;
1204      else
1205         img->Depth2 = 1;
1206      img->DepthLog2 = 0;
1207      break;
1208   case GL_TEXTURE_2D_ARRAY:
1209   case GL_PROXY_TEXTURE_2D_ARRAY:
1210      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
1211      img->HeightLog2 = _mesa_logbase2(img->Height2);
1212      img->Depth2 = depth; /* no border */
1213      img->DepthLog2 = 0; /* not used */
1214      break;
1215   case GL_TEXTURE_3D:
1216   case GL_PROXY_TEXTURE_3D:
1217      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
1218      img->HeightLog2 = _mesa_logbase2(img->Height2);
1219      img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
1220      img->DepthLog2 = _mesa_logbase2(img->Depth2);
1221      break;
1222   default:
1223      _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()",
1224                    target);
1225   }
1226
1227   img->MaxNumLevels =
1228      _mesa_get_tex_max_num_levels(target,
1229                                   img->Width2, img->Height2, img->Depth2);
1230   img->TexFormat = format;
1231}
1232
1233
1234/**
1235 * Free and clear fields of the gl_texture_image struct.
1236 *
1237 * \param ctx GL context.
1238 * \param texImage texture image structure to be cleared.
1239 *
1240 * After the call, \p texImage will have no data associated with it.  Its
1241 * fields are cleared so that its parent object will test incomplete.
1242 */
1243void
1244_mesa_clear_texture_image(struct gl_context *ctx,
1245                          struct gl_texture_image *texImage)
1246{
1247   ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
1248   clear_teximage_fields(texImage);
1249}
1250
1251
1252/**
1253 * This is the fallback for Driver.TestProxyTexImage().  Test the texture
1254 * level, width, height and depth against the ctx->Const limits for textures.
1255 *
1256 * A hardware driver might override this function if, for example, the
1257 * max 3D texture size is 512x512x64 (i.e. not a cube).
1258 *
1259 * Note that width, height, depth == 0 is not an error.  However, a
1260 * texture with zero width/height/depth will be considered "incomplete"
1261 * and texturing will effectively be disabled.
1262 *
1263 * \param target  one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
1264 *                GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
1265 *                GL_PROXY_TEXTURE_CUBE_MAP_ARB.
1266 * \param level  as passed to glTexImage
1267 * \param internalFormat  as passed to glTexImage
1268 * \param format  as passed to glTexImage
1269 * \param type  as passed to glTexImage
1270 * \param width  as passed to glTexImage
1271 * \param height  as passed to glTexImage
1272 * \param depth  as passed to glTexImage
1273 * \param border  as passed to glTexImage
1274 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
1275 */
1276GLboolean
1277_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
1278                          GLint internalFormat, GLenum format, GLenum type,
1279                          GLint width, GLint height, GLint depth, GLint border)
1280{
1281   GLint maxSize;
1282
1283   (void) internalFormat;
1284   (void) format;
1285   (void) type;
1286
1287   switch (target) {
1288   case GL_PROXY_TEXTURE_1D:
1289      if (level >= ctx->Const.MaxTextureLevels)
1290         return GL_FALSE;
1291      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1); /* level zero size */
1292      maxSize >>= level;  /* level size */
1293      if (width < 2 * border || width > 2 * border + maxSize)
1294         return GL_FALSE;
1295      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1296         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
1297            return GL_FALSE;
1298      }
1299      return GL_TRUE;
1300
1301   case GL_PROXY_TEXTURE_2D:
1302      if (level >= ctx->Const.MaxTextureLevels)
1303         return GL_FALSE;
1304      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
1305      maxSize >>= level;
1306      if (width < 2 * border || width > 2 * border + maxSize)
1307         return GL_FALSE;
1308      if (height < 2 * border || height > 2 * border + maxSize)
1309         return GL_FALSE;
1310      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1311         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
1312            return GL_FALSE;
1313         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
1314            return GL_FALSE;
1315      }
1316      return GL_TRUE;
1317
1318   case GL_PROXY_TEXTURE_3D:
1319      if (level >= ctx->Const.Max3DTextureLevels)
1320         return GL_FALSE;
1321      maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
1322      maxSize >>= level;
1323      if (width < 2 * border || width > 2 * border + maxSize)
1324         return GL_FALSE;
1325      if (height < 2 * border || height > 2 * border + maxSize)
1326         return GL_FALSE;
1327      if (depth < 2 * border || depth > 2 * border + maxSize)
1328         return GL_FALSE;
1329      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1330         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
1331            return GL_FALSE;
1332         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
1333            return GL_FALSE;
1334         if (depth > 0 && !_mesa_is_pow_two(depth - 2 * border))
1335            return GL_FALSE;
1336      }
1337      return GL_TRUE;
1338
1339   case GL_PROXY_TEXTURE_RECTANGLE_NV:
1340      if (level != 0)
1341         return GL_FALSE;
1342      maxSize = ctx->Const.MaxTextureRectSize;
1343      if (width < 0 || width > maxSize)
1344         return GL_FALSE;
1345      if (height < 0 || height > maxSize)
1346         return GL_FALSE;
1347      return GL_TRUE;
1348
1349   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
1350      if (level >= ctx->Const.MaxCubeTextureLevels)
1351         return GL_FALSE;
1352      maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
1353      maxSize >>= level;
1354      if (width < 2 * border || width > 2 * border + maxSize)
1355         return GL_FALSE;
1356      if (height < 2 * border || height > 2 * border + maxSize)
1357         return GL_FALSE;
1358      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1359         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
1360            return GL_FALSE;
1361         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
1362            return GL_FALSE;
1363      }
1364      return GL_TRUE;
1365
1366   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1367      if (level >= ctx->Const.MaxTextureLevels)
1368         return GL_FALSE;
1369      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
1370      maxSize >>= level;
1371      if (width < 2 * border || width > 2 * border + maxSize)
1372         return GL_FALSE;
1373      if (height < 1 || height > ctx->Const.MaxArrayTextureLayers)
1374         return GL_FALSE;
1375      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1376         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
1377            return GL_FALSE;
1378      }
1379      return GL_TRUE;
1380
1381   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1382      if (level >= ctx->Const.MaxTextureLevels)
1383         return GL_FALSE;
1384      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
1385      maxSize >>= level;
1386      if (width < 2 * border || width > 2 * border + maxSize)
1387         return GL_FALSE;
1388      if (height < 2 * border || height > 2 * border + maxSize)
1389         return GL_FALSE;
1390      if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers)
1391         return GL_FALSE;
1392      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1393         if (width > 0 && !_mesa_is_pow_two(width - 2 * border))
1394            return GL_FALSE;
1395         if (height > 0 && !_mesa_is_pow_two(height - 2 * border))
1396            return GL_FALSE;
1397      }
1398      return GL_TRUE;
1399
1400   default:
1401      _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
1402      return GL_FALSE;
1403   }
1404}
1405
1406
1407/**
1408 * Check if the memory used by the texture would exceed the driver's limit.
1409 * This lets us support a max 3D texture size of 8K (for example) but
1410 * prevents allocating a full 8K x 8K x 8K texture.
1411 * XXX this could be rolled into the proxy texture size test (above) but
1412 * we don't have the actual texture internal format at that point.
1413 */
1414static GLboolean
1415legal_texture_size(struct gl_context *ctx, gl_format format,
1416                   GLint width, GLint height, GLint depth)
1417{
1418   uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
1419   uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
1420   return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
1421}
1422
1423
1424/**
1425 * Return true if the format is only valid for glCompressedTexImage.
1426 */
1427static GLboolean
1428compressedteximage_only_format(const struct gl_context *ctx, GLenum format)
1429{
1430   switch (format) {
1431   case GL_ETC1_RGB8_OES:
1432   case GL_PALETTE4_RGB8_OES:
1433   case GL_PALETTE4_RGBA8_OES:
1434   case GL_PALETTE4_R5_G6_B5_OES:
1435   case GL_PALETTE4_RGBA4_OES:
1436   case GL_PALETTE4_RGB5_A1_OES:
1437   case GL_PALETTE8_RGB8_OES:
1438   case GL_PALETTE8_RGBA8_OES:
1439   case GL_PALETTE8_R5_G6_B5_OES:
1440   case GL_PALETTE8_RGBA4_OES:
1441   case GL_PALETTE8_RGB5_A1_OES:
1442      return GL_TRUE;
1443   default:
1444      return GL_FALSE;
1445   }
1446}
1447
1448
1449/**
1450 * Helper function to determine whether a target and specific compression
1451 * format are supported.
1452 */
1453static GLboolean
1454target_can_be_compressed(const struct gl_context *ctx, GLenum target,
1455                         GLenum intFormat)
1456{
1457   (void) intFormat;  /* not used yet */
1458
1459   switch (target) {
1460   case GL_TEXTURE_2D:
1461   case GL_PROXY_TEXTURE_2D:
1462      return GL_TRUE; /* true for any compressed format so far */
1463   case GL_PROXY_TEXTURE_CUBE_MAP:
1464   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1465   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1466   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1467   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1468   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1469   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1470      return ctx->Extensions.ARB_texture_cube_map;
1471   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1472   case GL_TEXTURE_2D_ARRAY_EXT:
1473      return (ctx->Extensions.MESA_texture_array ||
1474              ctx->Extensions.EXT_texture_array);
1475   default:
1476      return GL_FALSE;
1477   }
1478}
1479
1480
1481/**
1482 * Check if the given texture target value is legal for a
1483 * glTexImage1/2/3D call.
1484 */
1485static GLboolean
1486legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
1487{
1488   switch (dims) {
1489   case 1:
1490      switch (target) {
1491      case GL_TEXTURE_1D:
1492      case GL_PROXY_TEXTURE_1D:
1493         return _mesa_is_desktop_gl(ctx);
1494      default:
1495         return GL_FALSE;
1496      }
1497   case 2:
1498      switch (target) {
1499      case GL_TEXTURE_2D:
1500         return GL_TRUE;
1501      case GL_PROXY_TEXTURE_2D:
1502         return _mesa_is_desktop_gl(ctx);
1503      case GL_PROXY_TEXTURE_CUBE_MAP:
1504         return _mesa_is_desktop_gl(ctx)
1505            && ctx->Extensions.ARB_texture_cube_map;
1506      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1507      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1508      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1509      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1510      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1511      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1512         return ctx->Extensions.ARB_texture_cube_map;
1513      case GL_TEXTURE_RECTANGLE_NV:
1514      case GL_PROXY_TEXTURE_RECTANGLE_NV:
1515         return _mesa_is_desktop_gl(ctx)
1516            && ctx->Extensions.NV_texture_rectangle;
1517      case GL_TEXTURE_1D_ARRAY_EXT:
1518      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1519         return _mesa_is_desktop_gl(ctx)
1520            && (ctx->Extensions.MESA_texture_array ||
1521                ctx->Extensions.EXT_texture_array);
1522      default:
1523         return GL_FALSE;
1524      }
1525   case 3:
1526      switch (target) {
1527      case GL_TEXTURE_3D:
1528         return GL_TRUE;
1529      case GL_PROXY_TEXTURE_3D:
1530         return _mesa_is_desktop_gl(ctx);
1531      case GL_TEXTURE_2D_ARRAY_EXT:
1532         return (_mesa_is_desktop_gl(ctx)
1533                 && (ctx->Extensions.MESA_texture_array ||
1534                     ctx->Extensions.EXT_texture_array))
1535            || _mesa_is_gles3(ctx);
1536      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1537         return _mesa_is_desktop_gl(ctx)
1538            && (ctx->Extensions.MESA_texture_array ||
1539                ctx->Extensions.EXT_texture_array);
1540      default:
1541         return GL_FALSE;
1542      }
1543   default:
1544      _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
1545      return GL_FALSE;
1546   }
1547}
1548
1549
1550/**
1551 * Check if the given texture target value is legal for a
1552 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
1553 * The difference compared to legal_teximage_target() above is that
1554 * proxy targets are not supported.
1555 */
1556static GLboolean
1557legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target)
1558{
1559   switch (dims) {
1560   case 1:
1561      return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D;
1562   case 2:
1563      switch (target) {
1564      case GL_TEXTURE_2D:
1565         return GL_TRUE;
1566      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1567      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1568      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1569      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1570      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1571      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1572         return ctx->Extensions.ARB_texture_cube_map;
1573      case GL_TEXTURE_RECTANGLE_NV:
1574         return _mesa_is_desktop_gl(ctx)
1575            && ctx->Extensions.NV_texture_rectangle;
1576      case GL_TEXTURE_1D_ARRAY_EXT:
1577         return _mesa_is_desktop_gl(ctx)
1578            && (ctx->Extensions.MESA_texture_array ||
1579                ctx->Extensions.EXT_texture_array);
1580      default:
1581         return GL_FALSE;
1582      }
1583   case 3:
1584      switch (target) {
1585      case GL_TEXTURE_3D:
1586         return GL_TRUE;
1587      case GL_TEXTURE_2D_ARRAY_EXT:
1588         return (_mesa_is_desktop_gl(ctx)
1589                 && (ctx->Extensions.MESA_texture_array ||
1590                     ctx->Extensions.EXT_texture_array))
1591            || _mesa_is_gles3(ctx);
1592      default:
1593         return GL_FALSE;
1594      }
1595   default:
1596      _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
1597                    dims);
1598      return GL_FALSE;
1599   }
1600}
1601
1602
1603/**
1604 * Helper function to determine if a texture object is mutable (in terms
1605 * of GL_ARB_texture_storage).
1606 */
1607static GLboolean
1608mutable_tex_object(struct gl_context *ctx, GLenum target)
1609{
1610   if (ctx->Extensions.ARB_texture_storage) {
1611      struct gl_texture_object *texObj =
1612         _mesa_get_current_tex_object(ctx, target);
1613      return !texObj->Immutable;
1614   }
1615   return GL_TRUE;
1616}
1617
1618
1619GLenum
1620_mesa_es_error_check_format_and_type(GLenum format, GLenum type,
1621                                     unsigned dimensions)
1622{
1623   bool type_valid = true;
1624
1625   switch (format) {
1626   case GL_ALPHA:
1627   case GL_LUMINANCE:
1628   case GL_LUMINANCE_ALPHA:
1629      type_valid = (type == GL_UNSIGNED_BYTE
1630                    || type == GL_FLOAT
1631                    || type == GL_HALF_FLOAT_OES);
1632      break;
1633
1634   case GL_RGB:
1635      type_valid = (type == GL_UNSIGNED_BYTE
1636                    || type == GL_UNSIGNED_SHORT_5_6_5
1637                    || type == GL_FLOAT
1638                    || type == GL_HALF_FLOAT_OES);
1639      break;
1640
1641   case GL_RGBA:
1642      type_valid = (type == GL_UNSIGNED_BYTE
1643                    || type == GL_UNSIGNED_SHORT_4_4_4_4
1644                    || type == GL_UNSIGNED_SHORT_5_5_5_1
1645                    || type == GL_FLOAT
1646                    || type == GL_HALF_FLOAT_OES
1647                    || type == GL_UNSIGNED_INT_2_10_10_10_REV);
1648      break;
1649
1650   case GL_DEPTH_COMPONENT:
1651      /* This format is filtered against invalid dimensionalities elsewhere.
1652       */
1653      type_valid = (type == GL_UNSIGNED_SHORT
1654                    || type == GL_UNSIGNED_INT);
1655      break;
1656
1657   case GL_DEPTH_STENCIL:
1658      /* This format is filtered against invalid dimensionalities elsewhere.
1659       */
1660      type_valid = (type == GL_UNSIGNED_INT_24_8);
1661      break;
1662
1663   case GL_BGRA_EXT:
1664      type_valid = (type == GL_UNSIGNED_BYTE);
1665
1666      /* This feels like a bug in the EXT_texture_format_BGRA8888 spec, but
1667       * the format does not appear to be allowed for 3D textures in OpenGL
1668       * ES.
1669       */
1670      if (dimensions != 2)
1671         return GL_INVALID_VALUE;
1672
1673      break;
1674
1675   default:
1676      return GL_INVALID_VALUE;
1677   }
1678
1679   return type_valid ? GL_NO_ERROR : GL_INVALID_OPERATION;
1680}
1681
1682
1683
1684/**
1685 * Return expected size of a compressed texture.
1686 */
1687static GLuint
1688compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
1689                    GLenum glformat)
1690{
1691   gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
1692   return _mesa_format_image_size(mesaFormat, width, height, depth);
1693}
1694
1695
1696/*
1697 * Return compressed texture block size, in pixels.
1698 */
1699static void
1700get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
1701{
1702   gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
1703   _mesa_get_format_block_size(mesaFormat, bw, bh);
1704}
1705
1706
1707/**
1708 * Special value returned by error some texture error checking functions when
1709 * an error is detected and the proxy texture image's width/height/depth/format
1710 * fields should be zeroed-out.
1711 */
1712#define PROXY_ERROR 2
1713
1714
1715/**
1716 * Test the glTexImage[123]D() parameters for errors.
1717 *
1718 * \param ctx GL context.
1719 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1720 * \param target texture target given by the user.
1721 * \param level image level given by the user.
1722 * \param internalFormat internal format given by the user.
1723 * \param format pixel data format given by the user.
1724 * \param type pixel data type given by the user.
1725 * \param width image width given by the user.
1726 * \param height image height given by the user.
1727 * \param depth image depth given by the user.
1728 * \param border image border given by the user.
1729 *
1730 * \return PROXY_ERROR if there's an error that should zero-out the proxy image,
1731 *         GL_TRUE if a regular GL error is found, or GL_FALSE if no error,
1732 *
1733 * Verifies each of the parameters against the constants specified in
1734 * __struct gl_contextRec::Const and the supported extensions, and according
1735 * to the OpenGL specification.
1736 */
1737static GLenum
1738texture_error_check( struct gl_context *ctx,
1739                     GLuint dimensions, GLenum target,
1740                     GLint level, GLint internalFormat,
1741                     GLenum format, GLenum type,
1742                     GLint width, GLint height,
1743                     GLint depth, GLint border )
1744{
1745   const GLenum proxyTarget = _mesa_get_proxy_target(target);
1746   const GLboolean isProxy = target == proxyTarget;
1747   GLboolean sizeOK = GL_TRUE;
1748   GLboolean colorFormat;
1749   GLenum err;
1750
1751   /* Even though there are no color-index textures, we still have to support
1752    * uploading color-index data and remapping it to RGB via the
1753    * GL_PIXEL_MAP_I_TO_[RGBA] tables.
1754    */
1755   const GLboolean indexFormat = (format == GL_COLOR_INDEX);
1756
1757   /* Note: for proxy textures, some error conditions immediately generate
1758    * a GL error in the usual way.  But others do not generate a GL error.
1759    * Instead, they cause the width, height, depth, format fields of the
1760    * texture image to be zeroed-out.  The GL spec seems to indicate that the
1761    * zero-out behaviour is only used in cases related to memory allocation.
1762    */
1763
1764   /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1765   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1766      _mesa_error(ctx, GL_INVALID_VALUE,
1767                  "glTexImage%dD(level=%d)", dimensions, level);
1768      return GL_TRUE;
1769   }
1770
1771   /* Check border */
1772   if (border < 0 || border > 1 ||
1773       ((ctx->API != API_OPENGL ||
1774         target == GL_TEXTURE_RECTANGLE_NV ||
1775         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
1776      _mesa_error(ctx, GL_INVALID_VALUE,
1777                  "glTexImage%dD(border=%d)", dimensions, border);
1778      return GL_TRUE;
1779   }
1780
1781   if (width < 0 || height < 0 || depth < 0) {
1782      _mesa_error(ctx, GL_INVALID_VALUE,
1783                  "glTexImage%dD(width, height or depth < 0)", dimensions);
1784      return GL_TRUE;
1785   }
1786
1787   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1788    * combinations of format, internalFormat, and type that can be used.
1789    * Formats and types that require additional extensions (e.g., GL_FLOAT
1790    * requires GL_OES_texture_float) are filtered elsewhere.
1791    */
1792   if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
1793      if (format != internalFormat) {
1794         _mesa_error(ctx, GL_INVALID_OPERATION,
1795                     "glTexImage%dD(format = %s, internalFormat = %s)",
1796                     dimensions,
1797                     _mesa_lookup_enum_by_nr(format),
1798                     _mesa_lookup_enum_by_nr(internalFormat));
1799         return GL_TRUE;
1800      }
1801
1802      err = _mesa_es_error_check_format_and_type(format, type, dimensions);
1803      if (err != GL_NO_ERROR) {
1804         _mesa_error(ctx, err,
1805                     "glTexImage%dD(format = %s, type = %s)",
1806                     dimensions,
1807                     _mesa_lookup_enum_by_nr(format),
1808                     _mesa_lookup_enum_by_nr(type));
1809         return GL_TRUE;
1810      }
1811   }
1812
1813   /* Do this simple check before calling the TestProxyTexImage() function */
1814   if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
1815      sizeOK = (width == height);
1816   }
1817
1818   /*
1819    * Use the proxy texture driver hook to see if the size/level/etc are
1820    * legal.
1821    */
1822   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
1823                                                    internalFormat, format,
1824                                                    type, width, height,
1825                                                    depth, border);
1826   if (!sizeOK) {
1827      if (isProxy) {
1828         /* No GL error is recorded, but we need to zero-out the image dims */
1829         return PROXY_ERROR;
1830      }
1831      else {
1832         _mesa_error(ctx, GL_INVALID_VALUE,
1833                     "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
1834                     dimensions, level, width, height, depth);
1835         return GL_TRUE;
1836      }
1837   }
1838
1839   /* Check internalFormat */
1840   if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
1841      _mesa_error(ctx, GL_INVALID_VALUE,
1842                  "glTexImage%dD(internalFormat=%s)",
1843                  dimensions, _mesa_lookup_enum_by_nr(internalFormat));
1844      return GL_TRUE;
1845   }
1846
1847   /* Check incoming image format and type */
1848   err = _mesa_error_check_format_and_type(ctx, format, type);
1849   if (err != GL_NO_ERROR) {
1850      _mesa_error(ctx, err,
1851                  "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
1852                  dimensions, format, type);
1853      return GL_TRUE;
1854   }
1855
1856   /* make sure internal format and format basically agree */
1857   colorFormat = _mesa_is_color_format(format);
1858   if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
1859       (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
1860       (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
1861       (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
1862       (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
1863      _mesa_error(ctx, GL_INVALID_OPERATION,
1864                  "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
1865                  dimensions, internalFormat, format);
1866      return GL_TRUE;
1867   }
1868
1869   /* additional checks for ycbcr textures */
1870   if (internalFormat == GL_YCBCR_MESA) {
1871      ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1872      if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
1873          type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
1874         char message[100];
1875         _mesa_snprintf(message, sizeof(message),
1876                        "glTexImage%dD(format/type YCBCR mismatch)",
1877                        dimensions);
1878         _mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
1879         return GL_TRUE; /* error */
1880      }
1881      if (target != GL_TEXTURE_2D &&
1882          target != GL_PROXY_TEXTURE_2D &&
1883          target != GL_TEXTURE_RECTANGLE_NV &&
1884          target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
1885         _mesa_error(ctx, GL_INVALID_ENUM,
1886                     "glTexImage%dD(bad target for YCbCr texture)",
1887                     dimensions);
1888         return GL_TRUE;
1889      }
1890      if (border != 0) {
1891         char message[100];
1892         _mesa_snprintf(message, sizeof(message),
1893                        "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
1894                        dimensions, border);
1895         _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
1896         return GL_TRUE;
1897      }
1898   }
1899
1900   /* additional checks for depth textures */
1901   if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
1902      /* Only 1D, 2D, rect, array and cube textures supported, not 3D
1903       * Cubemaps are only supported for GL version > 3.0 or with EXT_gpu_shader4 */
1904      if (target != GL_TEXTURE_1D &&
1905          target != GL_PROXY_TEXTURE_1D &&
1906          target != GL_TEXTURE_2D &&
1907          target != GL_PROXY_TEXTURE_2D &&
1908          target != GL_TEXTURE_1D_ARRAY &&
1909          target != GL_PROXY_TEXTURE_1D_ARRAY &&
1910          target != GL_TEXTURE_2D_ARRAY &&
1911          target != GL_PROXY_TEXTURE_2D_ARRAY &&
1912          target != GL_TEXTURE_RECTANGLE_ARB &&
1913          target != GL_PROXY_TEXTURE_RECTANGLE_ARB &&
1914         !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) &&
1915           (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))) {
1916         _mesa_error(ctx, GL_INVALID_ENUM,
1917                     "glTexImage%dD(bad target for depth texture)",
1918                     dimensions);
1919         return GL_TRUE;
1920      }
1921   }
1922
1923   /* additional checks for compressed textures */
1924   if (_mesa_is_compressed_format(ctx, internalFormat)) {
1925      if (!target_can_be_compressed(ctx, target, internalFormat)) {
1926         _mesa_error(ctx, GL_INVALID_ENUM,
1927                     "glTexImage%dD(target can't be compressed)", dimensions);
1928         return GL_TRUE;
1929      }
1930      if (compressedteximage_only_format(ctx, internalFormat)) {
1931         _mesa_error(ctx, GL_INVALID_OPERATION,
1932                     "glTexImage%dD(no compression for format)", dimensions);
1933         return GL_TRUE;
1934      }
1935      if (border != 0) {
1936         _mesa_error(ctx, GL_INVALID_OPERATION,
1937                     "glTexImage%dD(border!=0)", dimensions);
1938         return GL_TRUE;
1939      }
1940   }
1941
1942   /* additional checks for integer textures */
1943   if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) &&
1944       (_mesa_is_enum_format_integer(format) !=
1945        _mesa_is_enum_format_integer(internalFormat))) {
1946      _mesa_error(ctx, GL_INVALID_OPERATION,
1947                  "glTexImage%dD(integer/non-integer format mismatch)",
1948                  dimensions);
1949      return GL_TRUE;
1950   }
1951
1952   if (!mutable_tex_object(ctx, target)) {
1953      _mesa_error(ctx, GL_INVALID_OPERATION,
1954                  "glTexImage%dD(immutable texture)", dimensions);
1955      return GL_TRUE;
1956   }
1957
1958   /* if we get here, the parameters are OK */
1959   return GL_FALSE;
1960}
1961
1962
1963/**
1964 * Error checking for glCompressedTexImage[123]D().
1965 * \param reason  returns reason for error, if any
1966 * \return error code or GL_NO_ERROR or PROXY_ERROR.
1967 */
1968static GLenum
1969compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
1970                               GLenum target, GLint level,
1971                               GLenum internalFormat, GLsizei width,
1972                               GLsizei height, GLsizei depth, GLint border,
1973                               GLsizei imageSize)
1974{
1975   const GLenum proxyTarget = _mesa_get_proxy_target(target);
1976   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
1977   GLint expectedSize;
1978   GLenum choose_format;
1979   GLenum choose_type;
1980   GLenum proxy_format;
1981   GLenum error = GL_NO_ERROR;
1982   char *reason = ""; /* no error */
1983
1984   if (!target_can_be_compressed(ctx, target, internalFormat)) {
1985      reason = "target";
1986      error = GL_INVALID_ENUM;
1987      goto error;
1988   }
1989
1990   /* This will detect any invalid internalFormat value */
1991   if (!_mesa_is_compressed_format(ctx, internalFormat)) {
1992      reason = "internalFormat";
1993      error = GL_INVALID_ENUM;
1994      goto error;
1995   }
1996
1997   switch (internalFormat) {
1998#if FEATURE_ES
1999   case GL_PALETTE4_RGB8_OES:
2000   case GL_PALETTE4_RGBA8_OES:
2001   case GL_PALETTE4_R5_G6_B5_OES:
2002   case GL_PALETTE4_RGBA4_OES:
2003   case GL_PALETTE4_RGB5_A1_OES:
2004   case GL_PALETTE8_RGB8_OES:
2005   case GL_PALETTE8_RGBA8_OES:
2006   case GL_PALETTE8_R5_G6_B5_OES:
2007   case GL_PALETTE8_RGBA4_OES:
2008   case GL_PALETTE8_RGB5_A1_OES:
2009      _mesa_cpal_compressed_format_type(internalFormat, &choose_format,
2010					&choose_type);
2011      proxy_format = choose_format;
2012
2013      /* check level (note that level should be zero or less!) */
2014      if (level > 0 || level < -maxLevels) {
2015	 reason = "level";
2016	 error = GL_INVALID_VALUE;
2017         goto error;
2018      }
2019
2020      if (dimensions != 2) {
2021	 reason = "compressed paletted textures must be 2D";
2022	 error = GL_INVALID_OPERATION;
2023         goto error;
2024      }
2025
2026      /* Figure out the expected texture size (in bytes).  This will be
2027       * checked against the actual size later.
2028       */
2029      expectedSize = _mesa_cpal_compressed_size(level, internalFormat,
2030						width, height);
2031
2032      /* This is for the benefit of the TestProxyTexImage below.  It expects
2033       * level to be non-negative.  OES_compressed_paletted_texture uses a
2034       * weird mechanism where the level specified to glCompressedTexImage2D
2035       * is -(n-1) number of levels in the texture, and the data specifies the
2036       * complete mipmap stack.  This is done to ensure the palette is the
2037       * same for all levels.
2038       */
2039      level = -level;
2040      break;
2041#endif
2042
2043   default:
2044      choose_format = GL_NONE;
2045      choose_type = GL_NONE;
2046      proxy_format = internalFormat;
2047
2048      /* check level */
2049      if (level < 0 || level >= maxLevels) {
2050	 reason = "level";
2051	 error = GL_INVALID_VALUE;
2052         goto error;
2053      }
2054
2055      /* Figure out the expected texture size (in bytes).  This will be
2056       * checked against the actual size later.
2057       */
2058      expectedSize = compressed_tex_size(width, height, depth, internalFormat);
2059      break;
2060   }
2061
2062   /* This should really never fail */
2063   if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
2064      reason = "internalFormat";
2065      error = GL_INVALID_ENUM;
2066      goto error;
2067   }
2068
2069   /* No compressed formats support borders at this time */
2070   if (border != 0) {
2071      reason = "border != 0";
2072      error = GL_INVALID_VALUE;
2073      goto error;
2074   }
2075
2076   /* For cube map, width must equal height */
2077   if (_mesa_is_cube_face(target) && width != height) {
2078      reason = "width != height";
2079      error = GL_INVALID_VALUE;
2080      goto error;
2081   }
2082
2083   /* check image sizes */
2084   if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
2085				      proxy_format, choose_format,
2086				      choose_type,
2087				      width, height, depth, border)) {
2088      /* See error comment above */
2089      if (target == proxyTarget) {
2090         return PROXY_ERROR;
2091      }
2092      reason = "invalid width, height or format";
2093      error = GL_INVALID_OPERATION;
2094      goto error;
2095   }
2096
2097   /* check image size in bytes */
2098   if (expectedSize != imageSize) {
2099      /* Per GL_ARB_texture_compression:  GL_INVALID_VALUE is generated [...]
2100       * if <imageSize> is not consistent with the format, dimensions, and
2101       * contents of the specified image.
2102       */
2103      reason = "imageSize inconsistant with width/height/format";
2104      error = GL_INVALID_VALUE;
2105      goto error;
2106   }
2107
2108   if (!mutable_tex_object(ctx, target)) {
2109      reason = "immutable texture";
2110      error = GL_INVALID_OPERATION;
2111      goto error;
2112   }
2113
2114   return GL_NO_ERROR;
2115
2116error:
2117   _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)", dimensions, reason);
2118   return error;
2119}
2120
2121
2122
2123/**
2124 * Test glTexSubImage[123]D() parameters for errors.
2125 *
2126 * \param ctx GL context.
2127 * \param dimensions texture image dimensions (must be 1, 2 or 3).
2128 * \param target texture target given by the user.
2129 * \param level image level given by the user.
2130 * \param xoffset sub-image x offset given by the user.
2131 * \param yoffset sub-image y offset given by the user.
2132 * \param zoffset sub-image z offset given by the user.
2133 * \param format pixel data format given by the user.
2134 * \param type pixel data type given by the user.
2135 * \param width image width given by the user.
2136 * \param height image height given by the user.
2137 * \param depth image depth given by the user.
2138 *
2139 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2140 *
2141 * Verifies each of the parameters against the constants specified in
2142 * __struct gl_contextRec::Const and the supported extensions, and according
2143 * to the OpenGL specification.
2144 */
2145static GLboolean
2146subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
2147                        GLenum target, GLint level,
2148                        GLint xoffset, GLint yoffset, GLint zoffset,
2149                        GLint width, GLint height, GLint depth,
2150                        GLenum format, GLenum type )
2151{
2152   GLenum err;
2153
2154   /* Basic level check */
2155   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
2156      _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
2157      return GL_TRUE;
2158   }
2159
2160   /* Check for negative sizes */
2161   if (width < 0) {
2162      _mesa_error(ctx, GL_INVALID_VALUE,
2163                  "glTexSubImage%dD(width=%d)", dimensions, width);
2164      return GL_TRUE;
2165   }
2166   if (height < 0 && dimensions > 1) {
2167      _mesa_error(ctx, GL_INVALID_VALUE,
2168                  "glTexSubImage%dD(height=%d)", dimensions, height);
2169      return GL_TRUE;
2170   }
2171   if (depth < 0 && dimensions > 2) {
2172      _mesa_error(ctx, GL_INVALID_VALUE,
2173                  "glTexSubImage%dD(depth=%d)", dimensions, depth);
2174      return GL_TRUE;
2175   }
2176
2177   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
2178    * combinations of format and type that can be used.  Formats and types
2179    * that require additional extensions (e.g., GL_FLOAT requires
2180    * GL_OES_texture_float) are filtered elsewhere.
2181    */
2182   if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
2183      err = _mesa_es_error_check_format_and_type(format, type, dimensions);
2184      if (err != GL_NO_ERROR) {
2185         _mesa_error(ctx, err,
2186                     "glTexSubImage%dD(format = %s, type = %s)",
2187                     dimensions,
2188                     _mesa_lookup_enum_by_nr(format),
2189                     _mesa_lookup_enum_by_nr(type));
2190         return GL_TRUE;
2191      }
2192   }
2193
2194   err = _mesa_error_check_format_and_type(ctx, format, type);
2195   if (err != GL_NO_ERROR) {
2196      _mesa_error(ctx, err,
2197                  "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)",
2198                  dimensions, format, type);
2199      return GL_TRUE;
2200   }
2201
2202   return GL_FALSE;
2203}
2204
2205
2206/**
2207 * Do second part of glTexSubImage which depends on the destination texture.
2208 * \return GL_TRUE if error recorded, GL_FALSE otherwise
2209 */
2210static GLboolean
2211subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
2212			 GLenum target, GLint level,
2213			 GLint xoffset, GLint yoffset, GLint zoffset,
2214			 GLint width, GLint height, GLint depth,
2215			 GLenum format, GLenum type,
2216			 const struct gl_texture_image *destTex )
2217{
2218   if (!destTex) {
2219      /* undefined image level */
2220      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
2221      return GL_TRUE;
2222   }
2223
2224   if (xoffset < -((GLint)destTex->Border)) {
2225      _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
2226                  dimensions);
2227      return GL_TRUE;
2228   }
2229   if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
2230      _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
2231                  dimensions);
2232      return GL_TRUE;
2233   }
2234   if (dimensions > 1) {
2235      GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destTex->Border;
2236      if (yoffset < -yBorder) {
2237         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
2238                     dimensions);
2239         return GL_TRUE;
2240      }
2241      if (yoffset + height > (GLint) destTex->Height + yBorder) {
2242         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
2243                     dimensions);
2244         return GL_TRUE;
2245      }
2246   }
2247   if (dimensions > 2) {
2248      GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : destTex->Border;
2249      if (zoffset < -zBorder) {
2250         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
2251         return GL_TRUE;
2252      }
2253      if (zoffset + depth  > (GLint) destTex->Depth + zBorder) {
2254         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
2255         return GL_TRUE;
2256      }
2257   }
2258
2259   if (_mesa_is_format_compressed(destTex->TexFormat)) {
2260      GLuint bw, bh;
2261
2262      if (compressedteximage_only_format(ctx, destTex->InternalFormat)) {
2263         _mesa_error(ctx, GL_INVALID_OPERATION,
2264               "glTexSubImage%dD(no compression for format)", dimensions);
2265         return GL_TRUE;
2266      }
2267
2268      /* do tests which depend on compression block size */
2269      _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh);
2270
2271      /* offset must be multiple of block size */
2272      if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
2273         _mesa_error(ctx, GL_INVALID_OPERATION,
2274                     "glTexSubImage%dD(xoffset = %d, yoffset = %d)",
2275                     dimensions, xoffset, yoffset);
2276         return GL_TRUE;
2277      }
2278      /* size must be multiple of bw by bh or equal to whole texture size */
2279      if ((width % bw != 0) && (GLuint) width != destTex->Width) {
2280         _mesa_error(ctx, GL_INVALID_OPERATION,
2281                     "glTexSubImage%dD(width = %d)", dimensions, width);
2282         return GL_TRUE;
2283      }
2284      if ((height % bh != 0) && (GLuint) height != destTex->Height) {
2285         _mesa_error(ctx, GL_INVALID_OPERATION,
2286                     "glTexSubImage%dD(height = %d)", dimensions, height);
2287         return GL_TRUE;
2288      }
2289   }
2290
2291   if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
2292      /* both source and dest must be integer-valued, or neither */
2293      if (_mesa_is_format_integer_color(destTex->TexFormat) !=
2294          _mesa_is_enum_format_integer(format)) {
2295         _mesa_error(ctx, GL_INVALID_OPERATION,
2296                     "glTexSubImage%dD(integer/non-integer format mismatch)",
2297                     dimensions);
2298         return GL_TRUE;
2299      }
2300   }
2301
2302   return GL_FALSE;
2303}
2304
2305
2306/**
2307 * Test glCopyTexImage[12]D() parameters for errors.
2308 *
2309 * \param ctx GL context.
2310 * \param dimensions texture image dimensions (must be 1, 2 or 3).
2311 * \param target texture target given by the user.
2312 * \param level image level given by the user.
2313 * \param internalFormat internal format given by the user.
2314 * \param width image width given by the user.
2315 * \param height image height given by the user.
2316 * \param border texture border.
2317 *
2318 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2319 *
2320 * Verifies each of the parameters against the constants specified in
2321 * __struct gl_contextRec::Const and the supported extensions, and according
2322 * to the OpenGL specification.
2323 */
2324static GLboolean
2325copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
2326                         GLenum target, GLint level, GLint internalFormat,
2327                         GLint width, GLint height, GLint border )
2328{
2329   const GLenum proxyTarget = _mesa_get_proxy_target(target);
2330   const GLenum type = GL_FLOAT;
2331   GLboolean sizeOK;
2332   GLint baseFormat;
2333
2334   /* check target */
2335   if (!legal_texsubimage_target(ctx, dimensions, target)) {
2336      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
2337                  dimensions, _mesa_lookup_enum_by_nr(target));
2338      return GL_TRUE;
2339   }
2340
2341   /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
2342   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
2343      _mesa_error(ctx, GL_INVALID_VALUE,
2344                  "glCopyTexImage%dD(level=%d)", dimensions, level);
2345      return GL_TRUE;
2346   }
2347
2348   /* Check that the source buffer is complete */
2349   if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
2350      if (ctx->ReadBuffer->_Status == 0) {
2351         _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2352      }
2353      if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2354         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2355                     "glCopyTexImage%dD(invalid readbuffer)", dimensions);
2356         return GL_TRUE;
2357      }
2358
2359      if (ctx->ReadBuffer->Visual.samples > 0) {
2360	 _mesa_error(ctx, GL_INVALID_OPERATION,
2361		     "glCopyTexImage%dD(multisample FBO)",
2362		     dimensions);
2363	 return GL_TRUE;
2364      }
2365   }
2366
2367   /* Check border */
2368   if (border < 0 || border > 1 ||
2369       ((ctx->API != API_OPENGL ||
2370         target == GL_TEXTURE_RECTANGLE_NV ||
2371         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
2372      _mesa_error(ctx, GL_INVALID_VALUE,
2373                  "glCopyTexImage%dD(border=%d)", dimensions, border);
2374      return GL_TRUE;
2375   }
2376
2377   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
2378    * internalFormat.
2379    */
2380   if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
2381      switch (internalFormat) {
2382      case GL_ALPHA:
2383      case GL_RGB:
2384      case GL_RGBA:
2385      case GL_LUMINANCE:
2386      case GL_LUMINANCE_ALPHA:
2387         break;
2388      default:
2389         _mesa_error(ctx, GL_INVALID_VALUE,
2390                     "glCopyTexImage%dD(internalFormat)", dimensions);
2391         return GL_TRUE;
2392      }
2393   }
2394
2395   baseFormat = _mesa_base_tex_format(ctx, internalFormat);
2396   if (baseFormat < 0) {
2397      _mesa_error(ctx, GL_INVALID_VALUE,
2398                  "glCopyTexImage%dD(internalFormat)", dimensions);
2399      return GL_TRUE;
2400   }
2401
2402   if (!_mesa_source_buffer_exists(ctx, baseFormat)) {
2403      _mesa_error(ctx, GL_INVALID_OPERATION,
2404                  "glCopyTexImage%dD(missing readbuffer)", dimensions);
2405      return GL_TRUE;
2406   }
2407
2408   /* From the EXT_texture_integer spec:
2409    *
2410    *     "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
2411    *      if the texture internalformat is an integer format and the read color
2412    *      buffer is not an integer format, or if the internalformat is not an
2413    *      integer format and the read color buffer is an integer format."
2414    */
2415   if (_mesa_is_color_format(internalFormat)) {
2416      struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
2417
2418      if (_mesa_is_enum_format_integer(rb->InternalFormat) !=
2419	  _mesa_is_enum_format_integer(internalFormat)) {
2420	 _mesa_error(ctx, GL_INVALID_OPERATION,
2421		     "glCopyTexImage%dD(integer vs non-integer)", dimensions);
2422	 return GL_TRUE;
2423      }
2424   }
2425
2426   /* Do size, level checking */
2427   sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
2428      ? (width == height) : 1;
2429
2430   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
2431                                                    internalFormat, baseFormat,
2432                                                    type, width, height,
2433                                                    1, border);
2434
2435   if (!sizeOK) {
2436      if (dimensions == 1) {
2437         _mesa_error(ctx, GL_INVALID_VALUE,
2438                     "glCopyTexImage1D(width=%d)", width);
2439      }
2440      else {
2441         ASSERT(dimensions == 2);
2442         _mesa_error(ctx, GL_INVALID_VALUE,
2443                     "glCopyTexImage2D(width=%d, height=%d)", width, height);
2444      }
2445      return GL_TRUE;
2446   }
2447
2448   if (_mesa_is_compressed_format(ctx, internalFormat)) {
2449      if (!target_can_be_compressed(ctx, target, internalFormat)) {
2450         _mesa_error(ctx, GL_INVALID_ENUM,
2451                     "glCopyTexImage%dD(target)", dimensions);
2452         return GL_TRUE;
2453      }
2454      if (compressedteximage_only_format(ctx, internalFormat)) {
2455         _mesa_error(ctx, GL_INVALID_OPERATION,
2456               "glCopyTexImage%dD(no compression for format)", dimensions);
2457         return GL_TRUE;
2458      }
2459      if (border != 0) {
2460         _mesa_error(ctx, GL_INVALID_OPERATION,
2461                     "glCopyTexImage%dD(border!=0)", dimensions);
2462         return GL_TRUE;
2463      }
2464   }
2465
2466   if (!mutable_tex_object(ctx, target)) {
2467      _mesa_error(ctx, GL_INVALID_OPERATION,
2468                  "glCopyTexImage%dD(immutable texture)", dimensions);
2469      return GL_TRUE;
2470   }
2471
2472   /* if we get here, the parameters are OK */
2473   return GL_FALSE;
2474}
2475
2476
2477/**
2478 * Test glCopyTexSubImage[12]D() parameters for errors.
2479 * Note that this is the first part of error checking.
2480 * See also copytexsubimage_error_check2() below for the second part.
2481 *
2482 * \param ctx GL context.
2483 * \param dimensions texture image dimensions (must be 1, 2 or 3).
2484 * \param target texture target given by the user.
2485 * \param level image level given by the user.
2486 *
2487 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2488 */
2489static GLboolean
2490copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
2491                              GLenum target, GLint level)
2492{
2493   /* Check that the source buffer is complete */
2494   if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
2495      if (ctx->ReadBuffer->_Status == 0) {
2496         _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2497      }
2498      if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2499         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2500                     "glCopyTexImage%dD(invalid readbuffer)", dimensions);
2501         return GL_TRUE;
2502      }
2503
2504      if (ctx->ReadBuffer->Visual.samples > 0) {
2505	 _mesa_error(ctx, GL_INVALID_OPERATION,
2506		     "glCopyTexSubImage%dD(multisample FBO)",
2507		     dimensions);
2508	 return GL_TRUE;
2509      }
2510   }
2511
2512   /* check target (proxies not allowed) */
2513   if (!legal_texsubimage_target(ctx, dimensions, target)) {
2514      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
2515                  dimensions, _mesa_lookup_enum_by_nr(target));
2516      return GL_TRUE;
2517   }
2518
2519   /* Check level */
2520   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
2521      _mesa_error(ctx, GL_INVALID_VALUE,
2522                  "glCopyTexSubImage%dD(level=%d)", dimensions, level);
2523      return GL_TRUE;
2524   }
2525
2526   return GL_FALSE;
2527}
2528
2529
2530/**
2531 * Second part of error checking for glCopyTexSubImage[12]D().
2532 * \param xoffset sub-image x offset given by the user.
2533 * \param yoffset sub-image y offset given by the user.
2534 * \param zoffset sub-image z offset given by the user.
2535 * \param width image width given by the user.
2536 * \param height image height given by the user.
2537 */
2538static GLboolean
2539copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
2540			      GLenum target, GLint level,
2541			      GLint xoffset, GLint yoffset, GLint zoffset,
2542			      GLsizei width, GLsizei height,
2543			      const struct gl_texture_image *teximage )
2544{
2545   /* check that dest tex image exists */
2546   if (!teximage) {
2547      _mesa_error(ctx, GL_INVALID_OPERATION,
2548                  "glCopyTexSubImage%dD(undefined texture level: %d)",
2549                  dimensions, level);
2550      return GL_TRUE;
2551   }
2552
2553   /* Check size */
2554   if (width < 0) {
2555      _mesa_error(ctx, GL_INVALID_VALUE,
2556                  "glCopyTexSubImage%dD(width=%d)", dimensions, width);
2557      return GL_TRUE;
2558   }
2559   if (dimensions > 1 && height < 0) {
2560      _mesa_error(ctx, GL_INVALID_VALUE,
2561                  "glCopyTexSubImage%dD(height=%d)", dimensions, height);
2562      return GL_TRUE;
2563   }
2564
2565   /* check x/y offsets */
2566   if (xoffset < -((GLint)teximage->Border)) {
2567      _mesa_error(ctx, GL_INVALID_VALUE,
2568                  "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
2569      return GL_TRUE;
2570   }
2571   if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
2572      _mesa_error(ctx, GL_INVALID_VALUE,
2573                  "glCopyTexSubImage%dD(xoffset+width)", dimensions);
2574      return GL_TRUE;
2575   }
2576   if (dimensions > 1) {
2577      GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : teximage->Border;
2578      if (yoffset < -yBorder) {
2579         _mesa_error(ctx, GL_INVALID_VALUE,
2580                     "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
2581         return GL_TRUE;
2582      }
2583      /* NOTE: we're adding the border here, not subtracting! */
2584      if (yoffset + height > (GLint) teximage->Height + yBorder) {
2585         _mesa_error(ctx, GL_INVALID_VALUE,
2586                     "glCopyTexSubImage%dD(yoffset+height)", dimensions);
2587         return GL_TRUE;
2588      }
2589   }
2590
2591   /* check z offset */
2592   if (dimensions > 2) {
2593      GLint zBorder = (target == GL_TEXTURE_2D_ARRAY) ? 0 : teximage->Border;
2594      if (zoffset < -zBorder) {
2595         _mesa_error(ctx, GL_INVALID_VALUE,
2596                     "glCopyTexSubImage%dD(zoffset)", dimensions);
2597         return GL_TRUE;
2598      }
2599      if (zoffset > (GLint) teximage->Depth + zBorder) {
2600         _mesa_error(ctx, GL_INVALID_VALUE,
2601                     "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
2602         return GL_TRUE;
2603      }
2604   }
2605
2606   if (_mesa_is_format_compressed(teximage->TexFormat)) {
2607      if (compressedteximage_only_format(ctx, teximage->InternalFormat)) {
2608         _mesa_error(ctx, GL_INVALID_OPERATION,
2609               "glCopyTexSubImage%dD(no compression for format)", dimensions);
2610         return GL_TRUE;
2611      }
2612      /* offset must be multiple of 4 */
2613      if ((xoffset & 3) || (yoffset & 3)) {
2614         _mesa_error(ctx, GL_INVALID_VALUE,
2615                     "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions);
2616         return GL_TRUE;
2617      }
2618      /* size must be multiple of 4 */
2619      if ((width & 3) != 0 && (GLuint) width != teximage->Width) {
2620         _mesa_error(ctx, GL_INVALID_VALUE,
2621                     "glCopyTexSubImage%dD(width)", dimensions);
2622         return GL_TRUE;
2623      }
2624      if ((height & 3) != 0 && (GLuint) height != teximage->Height) {
2625         _mesa_error(ctx, GL_INVALID_VALUE,
2626                     "glCopyTexSubImage%dD(height)", dimensions);
2627         return GL_TRUE;
2628      }
2629   }
2630
2631   if (teximage->InternalFormat == GL_YCBCR_MESA) {
2632      _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
2633      return GL_TRUE;
2634   }
2635
2636   if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
2637      _mesa_error(ctx, GL_INVALID_OPERATION,
2638                  "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)",
2639                  dimensions, teximage->_BaseFormat);
2640      return GL_TRUE;
2641   }
2642
2643   /* From the EXT_texture_integer spec:
2644    *
2645    *     "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
2646    *      if the texture internalformat is an integer format and the read color
2647    *      buffer is not an integer format, or if the internalformat is not an
2648    *      integer format and the read color buffer is an integer format."
2649    */
2650   if (_mesa_is_color_format(teximage->InternalFormat)) {
2651      struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
2652
2653      if (_mesa_is_format_integer_color(rb->Format) !=
2654	  _mesa_is_format_integer_color(teximage->TexFormat)) {
2655	 _mesa_error(ctx, GL_INVALID_OPERATION,
2656		     "glCopyTexImage%dD(integer vs non-integer)", dimensions);
2657	 return GL_TRUE;
2658      }
2659   }
2660
2661   /* if we get here, the parameters are OK */
2662   return GL_FALSE;
2663}
2664
2665
2666/** Callback info for walking over FBO hash table */
2667struct cb_info
2668{
2669   struct gl_context *ctx;
2670   struct gl_texture_object *texObj;
2671   GLuint level, face;
2672};
2673
2674
2675/**
2676 * Check render to texture callback.  Called from _mesa_HashWalk().
2677 */
2678static void
2679check_rtt_cb(GLuint key, void *data, void *userData)
2680{
2681   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2682   const struct cb_info *info = (struct cb_info *) userData;
2683   struct gl_context *ctx = info->ctx;
2684   const struct gl_texture_object *texObj = info->texObj;
2685   const GLuint level = info->level, face = info->face;
2686
2687   /* If this is a user-created FBO */
2688   if (_mesa_is_user_fbo(fb)) {
2689      GLuint i;
2690      /* check if any of the FBO's attachments point to 'texObj' */
2691      for (i = 0; i < BUFFER_COUNT; i++) {
2692         struct gl_renderbuffer_attachment *att = fb->Attachment + i;
2693         if (att->Type == GL_TEXTURE &&
2694             att->Texture == texObj &&
2695             att->TextureLevel == level &&
2696             att->CubeMapFace == face) {
2697            ASSERT(_mesa_get_attachment_teximage(att));
2698            /* Tell driver about the new renderbuffer texture */
2699            ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
2700            /* Mark fb status as indeterminate to force re-validation */
2701            fb->_Status = 0;
2702         }
2703      }
2704   }
2705}
2706
2707
2708/**
2709 * When a texture image is specified we have to check if it's bound to
2710 * any framebuffer objects (render to texture) in order to detect changes
2711 * in size or format since that effects FBO completeness.
2712 * Any FBOs rendering into the texture must be re-validated.
2713 */
2714void
2715_mesa_update_fbo_texture(struct gl_context *ctx,
2716                         struct gl_texture_object *texObj,
2717                         GLuint face, GLuint level)
2718{
2719   /* Only check this texture if it's been marked as RenderToTexture */
2720   if (texObj->_RenderToTexture) {
2721      struct cb_info info;
2722      info.ctx = ctx;
2723      info.texObj = texObj;
2724      info.level = level;
2725      info.face = face;
2726      _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info);
2727   }
2728}
2729
2730
2731/**
2732 * If the texture object's GenerateMipmap flag is set and we've
2733 * changed the texture base level image, regenerate the rest of the
2734 * mipmap levels now.
2735 */
2736static inline void
2737check_gen_mipmap(struct gl_context *ctx, GLenum target,
2738                 struct gl_texture_object *texObj, GLint level)
2739{
2740   ASSERT(target != GL_TEXTURE_CUBE_MAP);
2741   if (texObj->GenerateMipmap &&
2742       level == texObj->BaseLevel &&
2743       level < texObj->MaxLevel) {
2744      ASSERT(ctx->Driver.GenerateMipmap);
2745      ctx->Driver.GenerateMipmap(ctx, target, texObj);
2746   }
2747}
2748
2749
2750/** Debug helper: override the user-requested internal format */
2751static GLenum
2752override_internal_format(GLenum internalFormat, GLint width, GLint height)
2753{
2754#if 0
2755   if (internalFormat == GL_RGBA16F_ARB ||
2756       internalFormat == GL_RGBA32F_ARB) {
2757      printf("Convert rgba float tex to int %d x %d\n", width, height);
2758      return GL_RGBA;
2759   }
2760   else if (internalFormat == GL_RGB16F_ARB ||
2761            internalFormat == GL_RGB32F_ARB) {
2762      printf("Convert rgb float tex to int %d x %d\n", width, height);
2763      return GL_RGB;
2764   }
2765   else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB ||
2766            internalFormat == GL_LUMINANCE_ALPHA32F_ARB) {
2767      printf("Convert luminance float tex to int %d x %d\n", width, height);
2768      return GL_LUMINANCE_ALPHA;
2769   }
2770   else if (internalFormat == GL_LUMINANCE16F_ARB ||
2771            internalFormat == GL_LUMINANCE32F_ARB) {
2772      printf("Convert luminance float tex to int %d x %d\n", width, height);
2773      return GL_LUMINANCE;
2774   }
2775   else if (internalFormat == GL_ALPHA16F_ARB ||
2776            internalFormat == GL_ALPHA32F_ARB) {
2777      printf("Convert luminance float tex to int %d x %d\n", width, height);
2778      return GL_ALPHA;
2779   }
2780   /*
2781   else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
2782      internalFormat = GL_RGBA;
2783   }
2784   */
2785   else {
2786      return internalFormat;
2787   }
2788#else
2789   return internalFormat;
2790#endif
2791}
2792
2793
2794/**
2795 * Choose the actual hardware format for a texture image.
2796 * Try to use the same format as the previous image level when possible.
2797 * Otherwise, ask the driver for the best format.
2798 * It's important to try to choose a consistant format for all levels
2799 * for efficient texture memory layout/allocation.  In particular, this
2800 * comes up during automatic mipmap generation.
2801 */
2802gl_format
2803_mesa_choose_texture_format(struct gl_context *ctx,
2804                            struct gl_texture_object *texObj,
2805                            GLenum target, GLint level,
2806                            GLenum internalFormat, GLenum format, GLenum type)
2807{
2808   gl_format f;
2809
2810   /* see if we've already chosen a format for the previous level */
2811   if (level > 0) {
2812      struct gl_texture_image *prevImage =
2813	 _mesa_select_tex_image(ctx, texObj, target, level - 1);
2814      /* See if the prev level is defined and has an internal format which
2815       * matches the new internal format.
2816       */
2817      if (prevImage &&
2818          prevImage->Width > 0 &&
2819          prevImage->InternalFormat == internalFormat) {
2820         /* use the same format */
2821         ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE);
2822         return prevImage->TexFormat;
2823      }
2824   }
2825
2826   /* If the application requested compression to an S3TC format but we don't
2827    * have the DTXn library, force a generic compressed format instead.
2828    */
2829   if (internalFormat != format && format != GL_NONE) {
2830      const GLenum before = internalFormat;
2831
2832      switch (internalFormat) {
2833      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
2834         if (!ctx->Mesa_DXTn)
2835            internalFormat = GL_COMPRESSED_RGB;
2836         break;
2837      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
2838      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
2839      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
2840         if (!ctx->Mesa_DXTn)
2841            internalFormat = GL_COMPRESSED_RGBA;
2842         break;
2843      default:
2844         break;
2845      }
2846
2847      if (before != internalFormat) {
2848         _mesa_warning(ctx,
2849                       "DXT compression requested (%s), "
2850                       "but libtxc_dxtn library not installed.  Using %s "
2851                       "instead.",
2852                       _mesa_lookup_enum_by_nr(before),
2853                       _mesa_lookup_enum_by_nr(internalFormat));
2854      }
2855   }
2856
2857   /* choose format from scratch */
2858   f = ctx->Driver.ChooseTextureFormat(ctx, texObj->Target, internalFormat,
2859                                       format, type);
2860   ASSERT(f != MESA_FORMAT_NONE);
2861   return f;
2862}
2863
2864/**
2865 * Adjust pixel unpack params and image dimensions to strip off the
2866 * one-pixel texture border.
2867 *
2868 * Gallium and intel don't support texture borders.  They've seldem been used
2869 * and seldom been implemented correctly anyway.
2870 *
2871 * \param unpackNew returns the new pixel unpack parameters
2872 */
2873static void
2874strip_texture_border(GLenum target,
2875                     GLint *width, GLint *height, GLint *depth,
2876                     const struct gl_pixelstore_attrib *unpack,
2877                     struct gl_pixelstore_attrib *unpackNew)
2878{
2879   assert(width);
2880   assert(height);
2881   assert(depth);
2882
2883   *unpackNew = *unpack;
2884
2885   if (unpackNew->RowLength == 0)
2886      unpackNew->RowLength = *width;
2887
2888   if (unpackNew->ImageHeight == 0)
2889      unpackNew->ImageHeight = *height;
2890
2891   assert(*width >= 3);
2892   unpackNew->SkipPixels++;  /* skip the border */
2893   *width = *width - 2;      /* reduce the width by two border pixels */
2894
2895   /* The min height of a texture with a border is 3 */
2896   if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) {
2897      unpackNew->SkipRows++;  /* skip the border */
2898      *height = *height - 2;  /* reduce the height by two border pixels */
2899   }
2900
2901   if (*depth >= 3 && target != GL_TEXTURE_2D_ARRAY) {
2902      unpackNew->SkipImages++;  /* skip the border */
2903      *depth = *depth - 2;      /* reduce the depth by two border pixels */
2904   }
2905}
2906
2907
2908/**
2909 * Common code to implement all the glTexImage1D/2D/3D functions
2910 * as well as glCompressedTexImage1D/2D/3D.
2911 * \param compressed  only GL_TRUE for glCompressedTexImage1D/2D/3D calls.
2912 * \param format  the user's image format (only used if !compressed)
2913 * \param type  the user's image type (only used if !compressed)
2914 * \param imageSize  only used for glCompressedTexImage1D/2D/3D calls.
2915 */
2916static void
2917teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
2918         GLenum target, GLint level, GLint internalFormat,
2919         GLsizei width, GLsizei height, GLsizei depth,
2920         GLint border, GLenum format, GLenum type,
2921         GLsizei imageSize, const GLvoid *pixels)
2922{
2923   const char *func = compressed ? "glCompressedTexImage" : "glTexImage";
2924   GLenum error;
2925   struct gl_pixelstore_attrib unpack_no_border;
2926   const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
2927
2928   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2929
2930   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) {
2931      if (compressed)
2932         _mesa_debug(ctx,
2933                     "glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n",
2934                     dims,
2935                     _mesa_lookup_enum_by_nr(target), level,
2936                     _mesa_lookup_enum_by_nr(internalFormat),
2937                     width, height, depth, border, pixels);
2938      else
2939         _mesa_debug(ctx,
2940                     "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
2941                     dims,
2942                     _mesa_lookup_enum_by_nr(target), level,
2943                     _mesa_lookup_enum_by_nr(internalFormat),
2944                     width, height, depth, border,
2945                     _mesa_lookup_enum_by_nr(format),
2946                     _mesa_lookup_enum_by_nr(type), pixels);
2947   }
2948
2949   internalFormat = override_internal_format(internalFormat, width, height);
2950
2951   /* target error checking */
2952   if (!legal_teximage_target(ctx, dims, target)) {
2953      _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
2954                  func, dims, _mesa_lookup_enum_by_nr(target));
2955      return;
2956   }
2957
2958   /* general error checking */
2959   if (compressed) {
2960      error = compressed_texture_error_check(ctx, dims, target, level,
2961                                             internalFormat,
2962                                             width, height, depth,
2963                                             border, imageSize);
2964   }
2965   else {
2966      error = texture_error_check(ctx, dims, target, level, internalFormat,
2967                                  format, type, width, height, depth, border);
2968   }
2969
2970#if FEATURE_ES
2971   /* Here we convert a cpal compressed image into a regular glTexImage2D
2972    * call by decompressing the texture.  If we really want to support cpal
2973    * textures in any driver this would have to be changed.
2974    */
2975   if (compressed && !error && dims == 2) {
2976      switch (internalFormat) {
2977      case GL_PALETTE4_RGB8_OES:
2978      case GL_PALETTE4_RGBA8_OES:
2979      case GL_PALETTE4_R5_G6_B5_OES:
2980      case GL_PALETTE4_RGBA4_OES:
2981      case GL_PALETTE4_RGB5_A1_OES:
2982      case GL_PALETTE8_RGB8_OES:
2983      case GL_PALETTE8_RGBA8_OES:
2984      case GL_PALETTE8_R5_G6_B5_OES:
2985      case GL_PALETTE8_RGBA4_OES:
2986      case GL_PALETTE8_RGB5_A1_OES:
2987         _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
2988                                          width, height, imageSize, pixels);
2989         return;
2990      }
2991   }
2992#endif
2993
2994   if (_mesa_is_proxy_texture(target)) {
2995      /* Proxy texture: just clear or set state depending on error checking */
2996      struct gl_texture_image *texImage =
2997         get_proxy_tex_image(ctx, target, level);
2998      gl_format texFormat = MESA_FORMAT_NONE;
2999
3000      if (!error) {
3001         /* No parameter errors.  Choose a texture format and see if we
3002          * can really allocate the texture.
3003          */
3004         struct gl_texture_object *texObj =
3005            _mesa_get_current_tex_object(ctx, target);
3006         texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
3007                                                 internalFormat, format, type);
3008         if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
3009            error = PROXY_ERROR;
3010         }
3011      }
3012
3013      if (error == PROXY_ERROR) {
3014         /* image too large, etc.  Clear all proxy texture image parameters. */
3015         if (texImage)
3016            clear_teximage_fields(texImage);
3017      }
3018      else if (error == GL_FALSE) {
3019         /* no error: store the teximage parameters */
3020         if (texImage)
3021            _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
3022                                       border, internalFormat, texFormat);
3023      }
3024      else {
3025         /* other, regular error (was already recorded) */
3026      }
3027   }
3028   else {
3029      /* non-proxy target */
3030      const GLuint face = _mesa_tex_target_to_face(target);
3031      struct gl_texture_object *texObj;
3032      struct gl_texture_image *texImage;
3033
3034      if (error) {
3035         return;   /* error was recorded */
3036      }
3037
3038      /* Allow a hardware driver to just strip out the border, to provide
3039       * reliable but slightly incorrect hardware rendering instead of
3040       * rarely-tested software fallback rendering.
3041       */
3042      if (border && ctx->Const.StripTextureBorder) {
3043	 strip_texture_border(target, &width, &height, &depth, unpack,
3044			      &unpack_no_border);
3045         border = 0;
3046	 unpack = &unpack_no_border;
3047      }
3048
3049      if (ctx->NewState & _NEW_PIXEL)
3050	 _mesa_update_state(ctx);
3051
3052      texObj = _mesa_get_current_tex_object(ctx, target);
3053
3054      _mesa_lock_texture(ctx, texObj);
3055      {
3056	 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
3057
3058	 if (!texImage) {
3059	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
3060	 }
3061         else {
3062            gl_format texFormat;
3063
3064            ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
3065
3066            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
3067                                                    internalFormat, format,
3068                                                    type);
3069
3070            if (legal_texture_size(ctx, texFormat, width, height, depth)) {
3071               _mesa_init_teximage_fields(ctx, texImage,
3072                                          width, height, depth,
3073                                          border, internalFormat, texFormat);
3074
3075               /* Give the texture to the driver.  <pixels> may be null. */
3076               if (width > 0 && height > 0 && depth > 0) {
3077                  if (compressed) {
3078                     ctx->Driver.CompressedTexImage(ctx, dims, texImage,
3079                                                    imageSize, pixels);
3080                  }
3081                  else {
3082                     ctx->Driver.TexImage(ctx, dims, texImage, format,
3083                                          type, pixels, unpack);
3084                  }
3085               }
3086
3087               check_gen_mipmap(ctx, target, texObj, level);
3088
3089               _mesa_update_fbo_texture(ctx, texObj, face, level);
3090
3091               _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
3092            }
3093            else {
3094               _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
3095            }
3096         }
3097      }
3098      _mesa_unlock_texture(ctx, texObj);
3099   }
3100}
3101
3102
3103/*
3104 * Called from the API.  Note that width includes the border.
3105 */
3106void GLAPIENTRY
3107_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
3108                  GLsizei width, GLint border, GLenum format,
3109                  GLenum type, const GLvoid *pixels )
3110{
3111   GET_CURRENT_CONTEXT(ctx);
3112   teximage(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1,
3113            border, format, type, 0, pixels);
3114}
3115
3116
3117void GLAPIENTRY
3118_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
3119                  GLsizei width, GLsizei height, GLint border,
3120                  GLenum format, GLenum type,
3121                  const GLvoid *pixels )
3122{
3123   GET_CURRENT_CONTEXT(ctx);
3124   teximage(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1,
3125            border, format, type, 0, pixels);
3126}
3127
3128
3129/*
3130 * Called by the API or display list executor.
3131 * Note that width and height include the border.
3132 */
3133void GLAPIENTRY
3134_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
3135                  GLsizei width, GLsizei height, GLsizei depth,
3136                  GLint border, GLenum format, GLenum type,
3137                  const GLvoid *pixels )
3138{
3139   GET_CURRENT_CONTEXT(ctx);
3140   teximage(ctx, GL_FALSE, 3, target, level, internalFormat,
3141            width, height, depth,
3142            border, format, type, 0, pixels);
3143}
3144
3145
3146void GLAPIENTRY
3147_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
3148                     GLsizei width, GLsizei height, GLsizei depth,
3149                     GLint border, GLenum format, GLenum type,
3150                     const GLvoid *pixels )
3151{
3152   _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
3153                    depth, border, format, type, pixels);
3154}
3155
3156
3157#if FEATURE_OES_EGL_image
3158void GLAPIENTRY
3159_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
3160{
3161   struct gl_texture_object *texObj;
3162   struct gl_texture_image *texImage;
3163   bool valid_target;
3164   GET_CURRENT_CONTEXT(ctx);
3165   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3166
3167   switch (target) {
3168   case GL_TEXTURE_2D:
3169      valid_target = ctx->Extensions.OES_EGL_image;
3170      break;
3171   case GL_TEXTURE_EXTERNAL_OES:
3172      valid_target = ctx->Extensions.OES_EGL_image_external;
3173      break;
3174   default:
3175      valid_target = false;
3176      break;
3177   }
3178
3179   if (!valid_target) {
3180      _mesa_error(ctx, GL_INVALID_ENUM,
3181		  "glEGLImageTargetTexture2D(target=%d)", target);
3182      return;
3183   }
3184
3185   if (ctx->NewState & _NEW_PIXEL)
3186      _mesa_update_state(ctx);
3187
3188   texObj = _mesa_get_current_tex_object(ctx, target);
3189   _mesa_lock_texture(ctx, texObj);
3190
3191   if (texObj->Immutable) {
3192      _mesa_error(ctx, GL_INVALID_OPERATION,
3193		  "glEGLImageTargetTexture2D(texture is immutable)");
3194      _mesa_unlock_texture(ctx, texObj);
3195      return;
3196   }
3197
3198   texImage = _mesa_get_tex_image(ctx, texObj, target, 0);
3199   if (!texImage) {
3200      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D");
3201   } else {
3202      ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
3203
3204      ctx->Driver.EGLImageTargetTexture2D(ctx, target,
3205					  texObj, texImage, image);
3206
3207      _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
3208   }
3209   _mesa_unlock_texture(ctx, texObj);
3210
3211}
3212#endif
3213
3214
3215
3216/**
3217 * Implement all the glTexSubImage1/2/3D() functions.
3218 */
3219static void
3220texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
3221            GLint xoffset, GLint yoffset, GLint zoffset,
3222            GLsizei width, GLsizei height, GLsizei depth,
3223            GLenum format, GLenum type, const GLvoid *pixels )
3224{
3225   struct gl_texture_object *texObj;
3226   struct gl_texture_image *texImage;
3227
3228   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3229
3230   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3231      _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
3232                  dims,
3233                  _mesa_lookup_enum_by_nr(target), level,
3234                  xoffset, yoffset, zoffset, width, height, depth,
3235                  _mesa_lookup_enum_by_nr(format),
3236                  _mesa_lookup_enum_by_nr(type), pixels);
3237
3238   /* check target (proxies not allowed) */
3239   if (!legal_texsubimage_target(ctx, dims, target)) {
3240      _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
3241                  dims, _mesa_lookup_enum_by_nr(target));
3242      return;
3243   }
3244
3245   if (ctx->NewState & _NEW_PIXEL)
3246      _mesa_update_state(ctx);
3247
3248   if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset,
3249                              width, height, depth, format, type)) {
3250      return;   /* error was detected */
3251   }
3252
3253   texObj = _mesa_get_current_tex_object(ctx, target);
3254
3255   _mesa_lock_texture(ctx, texObj);
3256   {
3257      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
3258
3259      if (subtexture_error_check2(ctx, dims, target, level,
3260                                  xoffset, yoffset, zoffset,
3261				  width, height, depth,
3262                                  format, type, texImage)) {
3263         /* error was recorded */
3264      }
3265      else if (width > 0 && height > 0 && depth > 0) {
3266         /* If we have a border, offset=-1 is legal.  Bias by border width. */
3267         switch (dims) {
3268         case 3:
3269            if (target != GL_TEXTURE_2D_ARRAY)
3270               zoffset += texImage->Border;
3271            /* fall-through */
3272         case 2:
3273            if (target != GL_TEXTURE_1D_ARRAY)
3274               yoffset += texImage->Border;
3275            /* fall-through */
3276         case 1:
3277            xoffset += texImage->Border;
3278         }
3279
3280         ctx->Driver.TexSubImage(ctx, dims, texImage,
3281                                 xoffset, yoffset, zoffset,
3282                                 width, height, depth,
3283                                 format, type, pixels, &ctx->Unpack);
3284
3285         check_gen_mipmap(ctx, target, texObj, level);
3286
3287         ctx->NewState |= _NEW_TEXTURE;
3288      }
3289   }
3290   _mesa_unlock_texture(ctx, texObj);
3291}
3292
3293
3294void GLAPIENTRY
3295_mesa_TexSubImage1D( GLenum target, GLint level,
3296                     GLint xoffset, GLsizei width,
3297                     GLenum format, GLenum type,
3298                     const GLvoid *pixels )
3299{
3300   GET_CURRENT_CONTEXT(ctx);
3301   texsubimage(ctx, 1, target, level,
3302               xoffset, 0, 0,
3303               width, 1, 1,
3304               format, type, pixels);
3305}
3306
3307
3308void GLAPIENTRY
3309_mesa_TexSubImage2D( GLenum target, GLint level,
3310                     GLint xoffset, GLint yoffset,
3311                     GLsizei width, GLsizei height,
3312                     GLenum format, GLenum type,
3313                     const GLvoid *pixels )
3314{
3315   GET_CURRENT_CONTEXT(ctx);
3316   texsubimage(ctx, 2, target, level,
3317               xoffset, yoffset, 0,
3318               width, height, 1,
3319               format, type, pixels);
3320}
3321
3322
3323
3324void GLAPIENTRY
3325_mesa_TexSubImage3D( GLenum target, GLint level,
3326                     GLint xoffset, GLint yoffset, GLint zoffset,
3327                     GLsizei width, GLsizei height, GLsizei depth,
3328                     GLenum format, GLenum type,
3329                     const GLvoid *pixels )
3330{
3331   GET_CURRENT_CONTEXT(ctx);
3332   texsubimage(ctx, 3, target, level,
3333               xoffset, yoffset, zoffset,
3334               width, height, depth,
3335               format, type, pixels);
3336}
3337
3338
3339
3340/**
3341 * For glCopyTexSubImage, return the source renderbuffer to copy texel data
3342 * from.  This depends on whether the texture contains color or depth values.
3343 */
3344static struct gl_renderbuffer *
3345get_copy_tex_image_source(struct gl_context *ctx, gl_format texFormat)
3346{
3347   if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) {
3348      /* reading from depth/stencil buffer */
3349      return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
3350   }
3351   else {
3352      /* copying from color buffer */
3353      return ctx->ReadBuffer->_ColorReadBuffer;
3354   }
3355}
3356
3357
3358
3359/**
3360 * Implement the glCopyTexImage1/2D() functions.
3361 */
3362static void
3363copyteximage(struct gl_context *ctx, GLuint dims,
3364             GLenum target, GLint level, GLenum internalFormat,
3365             GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
3366{
3367   struct gl_texture_object *texObj;
3368   struct gl_texture_image *texImage;
3369   const GLuint face = _mesa_tex_target_to_face(target);
3370
3371   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3372
3373   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3374      _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
3375                  dims,
3376                  _mesa_lookup_enum_by_nr(target), level,
3377                  _mesa_lookup_enum_by_nr(internalFormat),
3378                  x, y, width, height, border);
3379
3380   if (ctx->NewState & NEW_COPY_TEX_STATE)
3381      _mesa_update_state(ctx);
3382
3383   if (copytexture_error_check(ctx, dims, target, level, internalFormat,
3384                               width, height, border))
3385      return;
3386
3387   texObj = _mesa_get_current_tex_object(ctx, target);
3388
3389   if (border && ctx->Const.StripTextureBorder) {
3390      x += border;
3391      width -= border * 2;
3392      if (dims == 2) {
3393	 y += border;
3394	 height -= border * 2;
3395      }
3396      border = 0;
3397   }
3398
3399   _mesa_lock_texture(ctx, texObj);
3400   {
3401      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
3402
3403      if (!texImage) {
3404	 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
3405      }
3406      else {
3407         /* choose actual hw format */
3408         gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
3409                                                           target, level,
3410                                                           internalFormat,
3411                                                           GL_NONE, GL_NONE);
3412
3413         if (legal_texture_size(ctx, texFormat, width, height, 1)) {
3414            GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0;
3415
3416            /* Free old texture image */
3417            ctx->Driver.FreeTextureImageBuffer(ctx, texImage);
3418
3419            _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
3420                                       border, internalFormat, texFormat);
3421
3422            /* Allocate texture memory (no pixel data yet) */
3423            ctx->Driver.TexImage(ctx, dims, texImage,
3424                                 GL_NONE, GL_NONE,
3425                                 NULL, &ctx->Unpack);
3426
3427            if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
3428                                           &width, &height)) {
3429               struct gl_renderbuffer *srcRb =
3430                  get_copy_tex_image_source(ctx, texImage->TexFormat);
3431
3432               ctx->Driver.CopyTexSubImage(ctx, dims, texImage, dstX, dstY, dstZ,
3433                                           srcRb, srcX, srcY, width, height);
3434            }
3435
3436            check_gen_mipmap(ctx, target, texObj, level);
3437
3438            _mesa_update_fbo_texture(ctx, texObj, face, level);
3439
3440            _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
3441         }
3442         else {
3443            /* probably too large of image */
3444            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
3445         }
3446      }
3447   }
3448   _mesa_unlock_texture(ctx, texObj);
3449}
3450
3451
3452
3453void GLAPIENTRY
3454_mesa_CopyTexImage1D( GLenum target, GLint level,
3455                      GLenum internalFormat,
3456                      GLint x, GLint y,
3457                      GLsizei width, GLint border )
3458{
3459   GET_CURRENT_CONTEXT(ctx);
3460   copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
3461}
3462
3463
3464
3465void GLAPIENTRY
3466_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
3467                      GLint x, GLint y, GLsizei width, GLsizei height,
3468                      GLint border )
3469{
3470   GET_CURRENT_CONTEXT(ctx);
3471   copyteximage(ctx, 2, target, level, internalFormat,
3472                x, y, width, height, border);
3473}
3474
3475
3476
3477/**
3478 * Implementation for glCopyTexSubImage1/2/3D() functions.
3479 */
3480static void
3481copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
3482                GLint xoffset, GLint yoffset, GLint zoffset,
3483                GLint x, GLint y, GLsizei width, GLsizei height)
3484{
3485   struct gl_texture_object *texObj;
3486   struct gl_texture_image *texImage;
3487
3488   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3489
3490   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3491      _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n",
3492                  dims,
3493                  _mesa_lookup_enum_by_nr(target),
3494                  level, xoffset, yoffset, zoffset, x, y, width, height);
3495
3496   if (ctx->NewState & NEW_COPY_TEX_STATE)
3497      _mesa_update_state(ctx);
3498
3499   if (copytexsubimage_error_check1(ctx, dims, target, level))
3500      return;
3501
3502   texObj = _mesa_get_current_tex_object(ctx, target);
3503
3504   _mesa_lock_texture(ctx, texObj);
3505   {
3506      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
3507
3508      if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset,
3509				       zoffset, width, height, texImage)) {
3510         /* error was recored */
3511      }
3512      else {
3513         /* If we have a border, offset=-1 is legal.  Bias by border width. */
3514         switch (dims) {
3515         case 3:
3516            if (target != GL_TEXTURE_2D_ARRAY)
3517               zoffset += texImage->Border;
3518            /* fall-through */
3519         case 2:
3520            if (target != GL_TEXTURE_1D_ARRAY)
3521               yoffset += texImage->Border;
3522            /* fall-through */
3523         case 1:
3524            xoffset += texImage->Border;
3525         }
3526
3527         if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
3528                                        &width, &height)) {
3529            struct gl_renderbuffer *srcRb =
3530               get_copy_tex_image_source(ctx, texImage->TexFormat);
3531
3532            ctx->Driver.CopyTexSubImage(ctx, dims, texImage,
3533                                        xoffset, yoffset, zoffset,
3534                                        srcRb, x, y, width, height);
3535
3536            check_gen_mipmap(ctx, target, texObj, level);
3537
3538            ctx->NewState |= _NEW_TEXTURE;
3539         }
3540      }
3541   }
3542   _mesa_unlock_texture(ctx, texObj);
3543}
3544
3545
3546void GLAPIENTRY
3547_mesa_CopyTexSubImage1D( GLenum target, GLint level,
3548                         GLint xoffset, GLint x, GLint y, GLsizei width )
3549{
3550   GET_CURRENT_CONTEXT(ctx);
3551   copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1);
3552}
3553
3554
3555
3556void GLAPIENTRY
3557_mesa_CopyTexSubImage2D( GLenum target, GLint level,
3558                         GLint xoffset, GLint yoffset,
3559                         GLint x, GLint y, GLsizei width, GLsizei height )
3560{
3561   GET_CURRENT_CONTEXT(ctx);
3562   copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y,
3563                   width, height);
3564}
3565
3566
3567
3568void GLAPIENTRY
3569_mesa_CopyTexSubImage3D( GLenum target, GLint level,
3570                         GLint xoffset, GLint yoffset, GLint zoffset,
3571                         GLint x, GLint y, GLsizei width, GLsizei height )
3572{
3573   GET_CURRENT_CONTEXT(ctx);
3574   copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
3575                   x, y, width, height);
3576}
3577
3578
3579
3580
3581/**********************************************************************/
3582/******                   Compressed Textures                    ******/
3583/**********************************************************************/
3584
3585
3586/**
3587 * Error checking for glCompressedTexSubImage[123]D().
3588 * \warning  There are some bad assumptions here about the size of compressed
3589 *           texture tiles (multiple of 4) used to test the validity of the
3590 *           offset and size parameters.
3591 * \return error code or GL_NO_ERROR.
3592 */
3593static GLenum
3594compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
3595                                  GLenum target, GLint level,
3596                                  GLint xoffset, GLint yoffset, GLint zoffset,
3597                                  GLsizei width, GLsizei height, GLsizei depth,
3598                                  GLenum format, GLsizei imageSize)
3599{
3600   GLint expectedSize, maxLevels = 0, maxTextureSize;
3601   GLuint bw, bh;
3602   (void) zoffset;
3603
3604   if (dimensions == 1) {
3605      /* 1D compressed textures not allowed */
3606      return GL_INVALID_ENUM;
3607   }
3608   else if (dimensions == 2) {
3609      if (target == GL_PROXY_TEXTURE_2D) {
3610         maxLevels = ctx->Const.MaxTextureLevels;
3611      }
3612      else if (target == GL_TEXTURE_2D) {
3613         maxLevels = ctx->Const.MaxTextureLevels;
3614      }
3615      else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
3616         if (!ctx->Extensions.ARB_texture_cube_map)
3617            return GL_INVALID_ENUM; /*target*/
3618         maxLevels = ctx->Const.MaxCubeTextureLevels;
3619      }
3620      else if (_mesa_is_cube_face(target)) {
3621         if (!ctx->Extensions.ARB_texture_cube_map)
3622            return GL_INVALID_ENUM; /*target*/
3623         maxLevels = ctx->Const.MaxCubeTextureLevels;
3624      }
3625      else {
3626         return GL_INVALID_ENUM; /*target*/
3627      }
3628   }
3629   else if (dimensions == 3) {
3630      /* 3D compressed textures not allowed */
3631      return GL_INVALID_ENUM;
3632   }
3633
3634   maxTextureSize = 1 << (maxLevels - 1);
3635
3636   /* this will catch any invalid compressed format token */
3637   if (!_mesa_is_compressed_format(ctx, format))
3638      return GL_INVALID_ENUM;
3639
3640   if (width < 0 || width > maxTextureSize)
3641      return GL_INVALID_VALUE;
3642
3643   if ((height < 0 || height > maxTextureSize)
3644       && dimensions > 1)
3645      return GL_INVALID_VALUE;
3646
3647   if (level < 0 || level >= maxLevels)
3648      return GL_INVALID_VALUE;
3649
3650   /*
3651    * do checks which depend on compression block size
3652    */
3653   get_compressed_block_size(format, &bw, &bh);
3654
3655   if ((xoffset % bw != 0) || (yoffset % bh != 0))
3656      return GL_INVALID_OPERATION;
3657
3658   if ((width % bw != 0) && width != 2 && width != 1)
3659      return GL_INVALID_OPERATION;
3660
3661   if ((height % bh != 0) && height != 2 && height != 1)
3662      return GL_INVALID_OPERATION;
3663
3664   expectedSize = compressed_tex_size(width, height, depth, format);
3665   if (expectedSize != imageSize)
3666      return GL_INVALID_VALUE;
3667
3668   return GL_NO_ERROR;
3669}
3670
3671
3672/**
3673 * Do second part of glCompressedTexSubImage error checking.
3674 * \return GL_TRUE if error found, GL_FALSE otherwise.
3675 */
3676static GLboolean
3677compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
3678                                   GLsizei width, GLsizei height,
3679                                   GLsizei depth, GLenum format,
3680                                   struct gl_texture_image *texImage)
3681{
3682   if (!texImage) {
3683      _mesa_error(ctx, GL_INVALID_OPERATION,
3684                  "glCompressedTexSubImage%uD(undefined image level)", dims);
3685      return GL_TRUE;
3686   }
3687
3688   if ((GLint) format != texImage->InternalFormat) {
3689      _mesa_error(ctx, GL_INVALID_OPERATION,
3690                  "glCompressedTexSubImage%uD(format=0x%x)", dims, format);
3691      return GL_TRUE;
3692   }
3693
3694   if (compressedteximage_only_format(ctx, format)) {
3695      _mesa_error(ctx, GL_INVALID_OPERATION,
3696                  "glCompressedTexSubImage%uD(format=0x%x cannot be updated)"
3697                  , dims, format);
3698      return GL_TRUE;
3699   }
3700
3701   if (((width == 1 || width == 2) &&
3702        width != (GLsizei) texImage->Width) ||
3703       (width > (GLsizei) texImage->Width)) {
3704      _mesa_error(ctx, GL_INVALID_VALUE,
3705                  "glCompressedTexSubImage%uD(width=%d)", dims, width);
3706      return GL_TRUE;
3707   }
3708
3709   if (dims >= 2) {
3710      if (((height == 1 || height == 2) &&
3711           height != (GLsizei) texImage->Height) ||
3712          (height > (GLsizei) texImage->Height)) {
3713         _mesa_error(ctx, GL_INVALID_VALUE,
3714                     "glCompressedTexSubImage%uD(height=%d)", dims, height);
3715         return GL_TRUE;
3716      }
3717   }
3718
3719   if (dims >= 3) {
3720      if (((depth == 1 || depth == 2) &&
3721           depth != (GLsizei) texImage->Depth) ||
3722          (depth > (GLsizei) texImage->Depth)) {
3723         _mesa_error(ctx, GL_INVALID_VALUE,
3724                     "glCompressedTexSubImage%uD(depth=%d)", dims, depth);
3725         return GL_TRUE;
3726      }
3727   }
3728
3729   return GL_FALSE;
3730}
3731
3732
3733void GLAPIENTRY
3734_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
3735                              GLenum internalFormat, GLsizei width,
3736                              GLint border, GLsizei imageSize,
3737                              const GLvoid *data)
3738{
3739   GET_CURRENT_CONTEXT(ctx);
3740   teximage(ctx, GL_TRUE, 1, target, level, internalFormat,
3741            width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data);
3742}
3743
3744
3745void GLAPIENTRY
3746_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
3747                              GLenum internalFormat, GLsizei width,
3748                              GLsizei height, GLint border, GLsizei imageSize,
3749                              const GLvoid *data)
3750{
3751   GET_CURRENT_CONTEXT(ctx);
3752   teximage(ctx, GL_TRUE, 2, target, level, internalFormat,
3753            width, height, 1, border, GL_NONE, GL_NONE, imageSize, data);
3754}
3755
3756
3757void GLAPIENTRY
3758_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
3759                              GLenum internalFormat, GLsizei width,
3760                              GLsizei height, GLsizei depth, GLint border,
3761                              GLsizei imageSize, const GLvoid *data)
3762{
3763   GET_CURRENT_CONTEXT(ctx);
3764   teximage(ctx, GL_TRUE, 3, target, level, internalFormat,
3765            width, height, depth, border, GL_NONE, GL_NONE, imageSize, data);
3766}
3767
3768
3769/**
3770 * Common helper for glCompressedTexSubImage1/2/3D().
3771 */
3772static void
3773compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
3774                         GLint xoffset, GLint yoffset, GLint zoffset,
3775                         GLsizei width, GLsizei height, GLsizei depth,
3776                         GLenum format, GLsizei imageSize, const GLvoid *data)
3777{
3778   struct gl_texture_object *texObj;
3779   struct gl_texture_image *texImage;
3780   GLenum error;
3781   GET_CURRENT_CONTEXT(ctx);
3782   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3783
3784   error = compressed_subtexture_error_check(ctx, dims, target, level,
3785                                             xoffset, 0, 0, /* pos */
3786                                             width, height, depth,   /* size */
3787                                             format, imageSize);
3788   if (error) {
3789      _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims);
3790      return;
3791   }
3792
3793   texObj = _mesa_get_current_tex_object(ctx, target);
3794
3795   _mesa_lock_texture(ctx, texObj);
3796   {
3797      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
3798
3799      if (compressed_subtexture_error_check2(ctx, dims, width, height, depth,
3800                                             format, texImage)) {
3801         /* error was recorded */
3802      }
3803      else if (width > 0 && height > 0 && depth > 0) {
3804         ctx->Driver.CompressedTexSubImage(ctx, dims, texImage,
3805                                           xoffset, yoffset, zoffset,
3806                                           width, height, depth,
3807                                           format, imageSize, data);
3808
3809         check_gen_mipmap(ctx, target, texObj, level);
3810
3811         ctx->NewState |= _NEW_TEXTURE;
3812      }
3813   }
3814   _mesa_unlock_texture(ctx, texObj);
3815}
3816
3817
3818void GLAPIENTRY
3819_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
3820                                 GLsizei width, GLenum format,
3821                                 GLsizei imageSize, const GLvoid *data)
3822{
3823   compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1,
3824                            format, imageSize, data);
3825}
3826
3827
3828void GLAPIENTRY
3829_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
3830                                 GLint yoffset, GLsizei width, GLsizei height,
3831                                 GLenum format, GLsizei imageSize,
3832                                 const GLvoid *data)
3833{
3834   compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0,
3835                            width, height, 1, format, imageSize, data);
3836}
3837
3838
3839void GLAPIENTRY
3840_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
3841                                 GLint yoffset, GLint zoffset, GLsizei width,
3842                                 GLsizei height, GLsizei depth, GLenum format,
3843                                 GLsizei imageSize, const GLvoid *data)
3844{
3845   compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset,
3846                            width, height, depth, format, imageSize, data);
3847}
3848
3849static gl_format
3850get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
3851{
3852   switch (internalFormat) {
3853   case GL_ALPHA8:
3854      return MESA_FORMAT_A8;
3855   case GL_ALPHA16:
3856      return MESA_FORMAT_A16;
3857   case GL_ALPHA16F_ARB:
3858      return MESA_FORMAT_ALPHA_FLOAT16;
3859   case GL_ALPHA32F_ARB:
3860      return MESA_FORMAT_ALPHA_FLOAT32;
3861   case GL_ALPHA8I_EXT:
3862      return MESA_FORMAT_ALPHA_INT8;
3863   case GL_ALPHA16I_EXT:
3864      return MESA_FORMAT_ALPHA_INT16;
3865   case GL_ALPHA32I_EXT:
3866      return MESA_FORMAT_ALPHA_INT32;
3867   case GL_ALPHA8UI_EXT:
3868      return MESA_FORMAT_ALPHA_UINT8;
3869   case GL_ALPHA16UI_EXT:
3870      return MESA_FORMAT_ALPHA_UINT16;
3871   case GL_ALPHA32UI_EXT:
3872      return MESA_FORMAT_ALPHA_UINT32;
3873   case GL_LUMINANCE8:
3874      return MESA_FORMAT_L8;
3875   case GL_LUMINANCE16:
3876      return MESA_FORMAT_L16;
3877   case GL_LUMINANCE16F_ARB:
3878      return MESA_FORMAT_LUMINANCE_FLOAT16;
3879   case GL_LUMINANCE32F_ARB:
3880      return MESA_FORMAT_LUMINANCE_FLOAT32;
3881   case GL_LUMINANCE8I_EXT:
3882      return MESA_FORMAT_LUMINANCE_INT8;
3883   case GL_LUMINANCE16I_EXT:
3884      return MESA_FORMAT_LUMINANCE_INT16;
3885   case GL_LUMINANCE32I_EXT:
3886      return MESA_FORMAT_LUMINANCE_INT32;
3887   case GL_LUMINANCE8UI_EXT:
3888      return MESA_FORMAT_LUMINANCE_UINT8;
3889   case GL_LUMINANCE16UI_EXT:
3890      return MESA_FORMAT_LUMINANCE_UINT16;
3891   case GL_LUMINANCE32UI_EXT:
3892      return MESA_FORMAT_LUMINANCE_UINT32;
3893   case GL_LUMINANCE8_ALPHA8:
3894      return MESA_FORMAT_AL88;
3895   case GL_LUMINANCE16_ALPHA16:
3896      return MESA_FORMAT_AL1616;
3897   case GL_LUMINANCE_ALPHA16F_ARB:
3898      return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
3899   case GL_LUMINANCE_ALPHA32F_ARB:
3900      return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
3901   case GL_LUMINANCE_ALPHA8I_EXT:
3902      return MESA_FORMAT_LUMINANCE_ALPHA_INT8;
3903   case GL_LUMINANCE_ALPHA16I_EXT:
3904      return MESA_FORMAT_LUMINANCE_ALPHA_INT8;
3905   case GL_LUMINANCE_ALPHA32I_EXT:
3906      return MESA_FORMAT_LUMINANCE_ALPHA_INT16;
3907   case GL_LUMINANCE_ALPHA8UI_EXT:
3908      return MESA_FORMAT_LUMINANCE_ALPHA_UINT8;
3909   case GL_LUMINANCE_ALPHA16UI_EXT:
3910      return MESA_FORMAT_LUMINANCE_ALPHA_UINT16;
3911   case GL_LUMINANCE_ALPHA32UI_EXT:
3912      return MESA_FORMAT_LUMINANCE_ALPHA_UINT32;
3913   case GL_INTENSITY8:
3914      return MESA_FORMAT_I8;
3915   case GL_INTENSITY16:
3916      return MESA_FORMAT_I16;
3917   case GL_INTENSITY16F_ARB:
3918      return MESA_FORMAT_INTENSITY_FLOAT16;
3919   case GL_INTENSITY32F_ARB:
3920      return MESA_FORMAT_INTENSITY_FLOAT32;
3921   case GL_INTENSITY8I_EXT:
3922      return MESA_FORMAT_INTENSITY_INT8;
3923   case GL_INTENSITY16I_EXT:
3924      return MESA_FORMAT_INTENSITY_INT16;
3925   case GL_INTENSITY32I_EXT:
3926      return MESA_FORMAT_INTENSITY_INT32;
3927   case GL_INTENSITY8UI_EXT:
3928      return MESA_FORMAT_INTENSITY_UINT8;
3929   case GL_INTENSITY16UI_EXT:
3930      return MESA_FORMAT_INTENSITY_UINT16;
3931   case GL_INTENSITY32UI_EXT:
3932      return MESA_FORMAT_INTENSITY_UINT32;
3933   case GL_RGBA8:
3934      return MESA_FORMAT_RGBA8888_REV;
3935   case GL_RGBA16:
3936      return MESA_FORMAT_RGBA_16;
3937   case GL_RGBA16F_ARB:
3938      return MESA_FORMAT_RGBA_FLOAT16;
3939   case GL_RGBA32F_ARB:
3940      return MESA_FORMAT_RGBA_FLOAT32;
3941   case GL_RGBA8I_EXT:
3942      return MESA_FORMAT_RGBA_INT8;
3943   case GL_RGBA16I_EXT:
3944      return MESA_FORMAT_RGBA_INT16;
3945   case GL_RGBA32I_EXT:
3946      return MESA_FORMAT_RGBA_INT32;
3947   case GL_RGBA8UI_EXT:
3948      return MESA_FORMAT_RGBA_UINT8;
3949   case GL_RGBA16UI_EXT:
3950      return MESA_FORMAT_RGBA_UINT16;
3951   case GL_RGBA32UI_EXT:
3952      return MESA_FORMAT_RGBA_UINT32;
3953
3954   case GL_RG8:
3955      return MESA_FORMAT_GR88;
3956   case GL_RG16:
3957      return MESA_FORMAT_RG1616;
3958   case GL_RG16F:
3959      return MESA_FORMAT_RG_FLOAT16;
3960   case GL_RG32F:
3961      return MESA_FORMAT_RG_FLOAT32;
3962   case GL_RG8I:
3963      return MESA_FORMAT_RG_INT8;
3964   case GL_RG16I:
3965      return MESA_FORMAT_RG_INT16;
3966   case GL_RG32I:
3967      return MESA_FORMAT_RG_INT32;
3968   case GL_RG8UI:
3969      return MESA_FORMAT_RG_UINT8;
3970   case GL_RG16UI:
3971      return MESA_FORMAT_RG_UINT16;
3972   case GL_RG32UI:
3973      return MESA_FORMAT_RG_UINT32;
3974
3975   case GL_R8:
3976      return MESA_FORMAT_R8;
3977   case GL_R16:
3978      return MESA_FORMAT_R16;
3979   case GL_R16F:
3980      return MESA_FORMAT_R_FLOAT16;
3981   case GL_R32F:
3982      return MESA_FORMAT_R_FLOAT32;
3983   case GL_R8I:
3984      return MESA_FORMAT_R_INT8;
3985   case GL_R16I:
3986      return MESA_FORMAT_R_INT16;
3987   case GL_R32I:
3988      return MESA_FORMAT_R_INT32;
3989   case GL_R8UI:
3990      return MESA_FORMAT_R_UINT8;
3991   case GL_R16UI:
3992      return MESA_FORMAT_R_UINT16;
3993   case GL_R32UI:
3994      return MESA_FORMAT_R_UINT32;
3995
3996   default:
3997      return MESA_FORMAT_NONE;
3998   }
3999}
4000
4001static gl_format
4002validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
4003{
4004   gl_format format = get_texbuffer_format(ctx, internalFormat);
4005   GLenum datatype;
4006
4007   if (format == MESA_FORMAT_NONE)
4008      return MESA_FORMAT_NONE;
4009
4010   datatype = _mesa_get_format_datatype(format);
4011   if (datatype == GL_FLOAT && !ctx->Extensions.ARB_texture_float)
4012      return MESA_FORMAT_NONE;
4013
4014   if (datatype == GL_HALF_FLOAT && !ctx->Extensions.ARB_half_float_pixel)
4015      return MESA_FORMAT_NONE;
4016
4017   /* The GL_ARB_texture_rg and GL_ARB_texture_buffer_object specs don't make
4018    * any mention of R/RG formats, but they appear in the GL 3.1 core
4019    * specification.
4020    */
4021   if (ctx->Version <= 30) {
4022      GLenum base_format = _mesa_get_format_base_format(format);
4023
4024      if (base_format == GL_R || base_format == GL_RG)
4025	 return MESA_FORMAT_NONE;
4026   }
4027   return format;
4028}
4029
4030
4031/** GL_ARB_texture_buffer_object */
4032void GLAPIENTRY
4033_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
4034{
4035   struct gl_texture_object *texObj;
4036   struct gl_buffer_object *bufObj;
4037   gl_format format;
4038
4039   GET_CURRENT_CONTEXT(ctx);
4040   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
4041
4042   if (!(ctx->Extensions.ARB_texture_buffer_object
4043         && _mesa_is_desktop_gl(ctx))) {
4044      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer");
4045      return;
4046   }
4047
4048   if (target != GL_TEXTURE_BUFFER_ARB) {
4049      _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(target)");
4050      return;
4051   }
4052
4053   format = validate_texbuffer_format(ctx, internalFormat);
4054   if (format == MESA_FORMAT_NONE) {
4055      _mesa_error(ctx, GL_INVALID_ENUM, "glTexBuffer(internalFormat 0x%x)",
4056                  internalFormat);
4057      return;
4058   }
4059
4060   bufObj = _mesa_lookup_bufferobj(ctx, buffer);
4061   if (buffer && !bufObj) {
4062      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBuffer(buffer %u)", buffer);
4063      return;
4064   }
4065
4066   texObj = _mesa_get_current_tex_object(ctx, target);
4067
4068   _mesa_lock_texture(ctx, texObj);
4069   {
4070      _mesa_reference_buffer_object(ctx, &texObj->BufferObject, bufObj);
4071      texObj->BufferObjectFormat = internalFormat;
4072      texObj->_BufferObjectFormat = format;
4073   }
4074   _mesa_unlock_texture(ctx, texObj);
4075}
4076