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