teximage.c revision 4ff70b7a8f5f6383d8f320e68d798d0654799210
1/*
2 * mesa 3-D graphics library
3 * Version:  7.6
4 *
5 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27/**
28 * \file teximage.c
29 * Texture image-related functions.
30 */
31
32
33#include "glheader.h"
34#include "bufferobj.h"
35#include "context.h"
36#include "enums.h"
37#include "fbobject.h"
38#include "framebuffer.h"
39#include "hash.h"
40#include "image.h"
41#include "imports.h"
42#include "macros.h"
43#include "state.h"
44#include "texcompress.h"
45#include "texfetch.h"
46#include "teximage.h"
47#include "texstate.h"
48#include "texpal.h"
49#include "mtypes.h"
50
51
52/**
53 * State changes which we care about for glCopyTex[Sub]Image() calls.
54 * In particular, we care about pixel transfer state and buffer state
55 * (such as glReadBuffer to make sure we read from the right renderbuffer).
56 */
57#define NEW_COPY_TEX_STATE (_MESA_NEW_TRANSFER_STATE | \
58                            _NEW_BUFFERS | \
59                            _NEW_PIXEL)
60
61
62
63/**
64 * We allocate texture memory on 512-byte boundaries so we can use MMX/SSE
65 * elsewhere.
66 */
67void *
68_mesa_alloc_texmemory(GLsizei bytes)
69{
70   return _mesa_align_malloc(bytes, 512);
71}
72
73
74/**
75 * Free texture memory allocated with _mesa_alloc_texmemory()
76 */
77void
78_mesa_free_texmemory(void *m)
79{
80   _mesa_align_free(m);
81}
82
83
84/*
85 * Compute floor(log_base_2(n)).
86 * If n < 0 return -1.
87 */
88static int
89logbase2( int n )
90{
91   GLint i = 1;
92   GLint log2 = 0;
93
94   if (n < 0)
95      return -1;
96
97   if (n == 0)
98      return 0;
99
100   while ( n > i ) {
101      i *= 2;
102      log2++;
103   }
104   if (i != n) {
105      return log2 - 1;
106   }
107   else {
108      return log2;
109   }
110}
111
112
113
114/**
115 * Return the simple base format for a given internal texture format.
116 * For example, given GL_LUMINANCE12_ALPHA4, return GL_LUMINANCE_ALPHA.
117 *
118 * \param ctx GL context.
119 * \param internalFormat the internal texture format token or 1, 2, 3, or 4.
120 *
121 * \return the corresponding \u base internal format (GL_ALPHA, GL_LUMINANCE,
122 * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA), or -1 if invalid enum.
123 *
124 * This is the format which is used during texture application (i.e. the
125 * texture format and env mode determine the arithmetic used.
126 *
127 * XXX this could be static
128 */
129GLint
130_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat )
131{
132   switch (internalFormat) {
133      case GL_ALPHA:
134      case GL_ALPHA4:
135      case GL_ALPHA8:
136      case GL_ALPHA12:
137      case GL_ALPHA16:
138         return GL_ALPHA;
139      case 1:
140      case GL_LUMINANCE:
141      case GL_LUMINANCE4:
142      case GL_LUMINANCE8:
143      case GL_LUMINANCE12:
144      case GL_LUMINANCE16:
145         return GL_LUMINANCE;
146      case 2:
147      case GL_LUMINANCE_ALPHA:
148      case GL_LUMINANCE4_ALPHA4:
149      case GL_LUMINANCE6_ALPHA2:
150      case GL_LUMINANCE8_ALPHA8:
151      case GL_LUMINANCE12_ALPHA4:
152      case GL_LUMINANCE12_ALPHA12:
153      case GL_LUMINANCE16_ALPHA16:
154         return GL_LUMINANCE_ALPHA;
155      case GL_INTENSITY:
156      case GL_INTENSITY4:
157      case GL_INTENSITY8:
158      case GL_INTENSITY12:
159      case GL_INTENSITY16:
160         return GL_INTENSITY;
161      case 3:
162      case GL_RGB:
163      case GL_R3_G3_B2:
164      case GL_RGB4:
165      case GL_RGB5:
166      case GL_RGB8:
167      case GL_RGB10:
168      case GL_RGB12:
169      case GL_RGB16:
170         return GL_RGB;
171      case 4:
172      case GL_RGBA:
173      case GL_RGBA2:
174      case GL_RGBA4:
175      case GL_RGB5_A1:
176      case GL_RGBA8:
177      case GL_RGB10_A2:
178      case GL_RGBA12:
179      case GL_RGBA16:
180         return GL_RGBA;
181      default:
182         ; /* fallthrough */
183   }
184
185   if (ctx->Extensions.EXT_paletted_texture) {
186      switch (internalFormat) {
187         case GL_COLOR_INDEX:
188         case GL_COLOR_INDEX1_EXT:
189         case GL_COLOR_INDEX2_EXT:
190         case GL_COLOR_INDEX4_EXT:
191         case GL_COLOR_INDEX8_EXT:
192         case GL_COLOR_INDEX12_EXT:
193         case GL_COLOR_INDEX16_EXT:
194            return GL_COLOR_INDEX;
195         default:
196            ; /* fallthrough */
197      }
198   }
199
200   if (ctx->Extensions.ARB_depth_texture) {
201      switch (internalFormat) {
202         case GL_DEPTH_COMPONENT:
203         case GL_DEPTH_COMPONENT16:
204         case GL_DEPTH_COMPONENT24:
205         case GL_DEPTH_COMPONENT32:
206            return GL_DEPTH_COMPONENT;
207         default:
208            ; /* fallthrough */
209      }
210   }
211
212   switch (internalFormat) {
213   case GL_COMPRESSED_ALPHA:
214      return GL_ALPHA;
215   case GL_COMPRESSED_LUMINANCE:
216      return GL_LUMINANCE;
217   case GL_COMPRESSED_LUMINANCE_ALPHA:
218      return GL_LUMINANCE_ALPHA;
219   case GL_COMPRESSED_INTENSITY:
220      return GL_INTENSITY;
221   case GL_COMPRESSED_RGB:
222      return GL_RGB;
223   case GL_COMPRESSED_RGBA:
224      return GL_RGBA;
225   default:
226      ; /* fallthrough */
227   }
228
229   if (ctx->Extensions.TDFX_texture_compression_FXT1) {
230      switch (internalFormat) {
231         case GL_COMPRESSED_RGB_FXT1_3DFX:
232            return GL_RGB;
233         case GL_COMPRESSED_RGBA_FXT1_3DFX:
234            return GL_RGBA;
235         default:
236            ; /* fallthrough */
237      }
238   }
239
240   if (ctx->Extensions.EXT_texture_compression_s3tc) {
241      switch (internalFormat) {
242         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
243            return GL_RGB;
244         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
245         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
246         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
247            return GL_RGBA;
248         default:
249            ; /* fallthrough */
250      }
251   }
252
253   if (ctx->Extensions.S3_s3tc) {
254      switch (internalFormat) {
255         case GL_RGB_S3TC:
256         case GL_RGB4_S3TC:
257            return GL_RGB;
258         case GL_RGBA_S3TC:
259         case GL_RGBA4_S3TC:
260            return GL_RGBA;
261         default:
262            ; /* fallthrough */
263      }
264   }
265
266   if (ctx->Extensions.MESA_ycbcr_texture) {
267      if (internalFormat == GL_YCBCR_MESA)
268         return GL_YCBCR_MESA;
269   }
270
271   if (ctx->Extensions.ARB_texture_float) {
272      switch (internalFormat) {
273         case GL_ALPHA16F_ARB:
274         case GL_ALPHA32F_ARB:
275            return GL_ALPHA;
276         case GL_RGBA16F_ARB:
277         case GL_RGBA32F_ARB:
278            return GL_RGBA;
279         case GL_RGB16F_ARB:
280         case GL_RGB32F_ARB:
281            return GL_RGB;
282         case GL_INTENSITY16F_ARB:
283         case GL_INTENSITY32F_ARB:
284            return GL_INTENSITY;
285         case GL_LUMINANCE16F_ARB:
286         case GL_LUMINANCE32F_ARB:
287            return GL_LUMINANCE;
288         case GL_LUMINANCE_ALPHA16F_ARB:
289         case GL_LUMINANCE_ALPHA32F_ARB:
290            return GL_LUMINANCE_ALPHA;
291         default:
292            ; /* fallthrough */
293      }
294   }
295
296   if (ctx->Extensions.ATI_envmap_bumpmap) {
297      switch (internalFormat) {
298         case GL_DUDV_ATI:
299         case GL_DU8DV8_ATI:
300            return GL_DUDV_ATI;
301         default:
302            ; /* fallthrough */
303      }
304   }
305
306   if (ctx->Extensions.MESA_texture_signed_rgba) {
307      switch (internalFormat) {
308         case GL_RGBA_SNORM:
309         case GL_RGBA8_SNORM:
310            return GL_RGBA;
311         default:
312            ; /* fallthrough */
313      }
314   }
315
316   if (ctx->Extensions.EXT_packed_depth_stencil) {
317      switch (internalFormat) {
318         case GL_DEPTH_STENCIL_EXT:
319         case GL_DEPTH24_STENCIL8_EXT:
320            return GL_DEPTH_STENCIL_EXT;
321         default:
322            ; /* fallthrough */
323      }
324   }
325
326#if FEATURE_EXT_texture_sRGB
327   if (ctx->Extensions.EXT_texture_sRGB) {
328      switch (internalFormat) {
329      case GL_SRGB_EXT:
330      case GL_SRGB8_EXT:
331      case GL_COMPRESSED_SRGB_EXT:
332      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
333         return GL_RGB;
334      case GL_SRGB_ALPHA_EXT:
335      case GL_SRGB8_ALPHA8_EXT:
336      case GL_COMPRESSED_SRGB_ALPHA_EXT:
337      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
338      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
339      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
340         return GL_RGBA;
341      case GL_SLUMINANCE_ALPHA_EXT:
342      case GL_SLUMINANCE8_ALPHA8_EXT:
343      case GL_COMPRESSED_SLUMINANCE_EXT:
344      case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
345         return GL_LUMINANCE_ALPHA;
346      case GL_SLUMINANCE_EXT:
347      case GL_SLUMINANCE8_EXT:
348         return GL_LUMINANCE;
349      default:
350         ; /* fallthrough */
351      }
352   }
353#endif /* FEATURE_EXT_texture_sRGB */
354
355   if (ctx->Extensions.EXT_texture_integer) {
356      switch (internalFormat) {
357      case GL_RGBA8UI_EXT:
358      case GL_RGBA16UI_EXT:
359      case GL_RGBA32UI_EXT:
360      case GL_RGBA8I_EXT:
361      case GL_RGBA16I_EXT:
362      case GL_RGBA32I_EXT:
363         return GL_RGBA;
364      case GL_RGB8UI_EXT:
365      case GL_RGB16UI_EXT:
366      case GL_RGB32UI_EXT:
367      case GL_RGB8I_EXT:
368      case GL_RGB16I_EXT:
369      case GL_RGB32I_EXT:
370         return GL_RGB;
371      case GL_ALPHA8UI_EXT:
372      case GL_ALPHA16UI_EXT:
373      case GL_ALPHA32UI_EXT:
374      case GL_ALPHA8I_EXT:
375      case GL_ALPHA16I_EXT:
376      case GL_ALPHA32I_EXT:
377         return GL_ALPHA;
378      case GL_INTENSITY8UI_EXT:
379      case GL_INTENSITY16UI_EXT:
380      case GL_INTENSITY32UI_EXT:
381      case GL_INTENSITY8I_EXT:
382      case GL_INTENSITY16I_EXT:
383      case GL_INTENSITY32I_EXT:
384         return GL_INTENSITY;
385      case GL_LUMINANCE8UI_EXT:
386      case GL_LUMINANCE16UI_EXT:
387      case GL_LUMINANCE32UI_EXT:
388      case GL_LUMINANCE8I_EXT:
389      case GL_LUMINANCE16I_EXT:
390      case GL_LUMINANCE32I_EXT:
391         return GL_LUMINANCE;
392      case GL_LUMINANCE_ALPHA8UI_EXT:
393      case GL_LUMINANCE_ALPHA16UI_EXT:
394      case GL_LUMINANCE_ALPHA32UI_EXT:
395      case GL_LUMINANCE_ALPHA8I_EXT:
396      case GL_LUMINANCE_ALPHA16I_EXT:
397      case GL_LUMINANCE_ALPHA32I_EXT:
398         return GL_LUMINANCE_ALPHA;
399      default:
400         ; /* fallthrough */
401      }
402   }
403
404   if (ctx->Extensions.ARB_texture_rg) {
405      switch (internalFormat) {
406      case GL_R16F:
407	 /* R16F depends on both ARB_half_float_pixel and ARB_texture_float.
408	  */
409	 if (!ctx->Extensions.ARB_half_float_pixel)
410	    break;
411	 /* FALLTHROUGH */
412      case GL_R32F:
413	 if (!ctx->Extensions.ARB_texture_float)
414	    break;
415         return GL_RED;
416      case GL_R8I:
417      case GL_R8UI:
418      case GL_R16I:
419      case GL_R16UI:
420      case GL_R32I:
421      case GL_R32UI:
422	 if (!ctx->Extensions.EXT_texture_integer)
423	    break;
424	 /* FALLTHROUGH */
425      case GL_R8:
426      case GL_R16:
427      case GL_RED:
428      case GL_COMPRESSED_RED:
429         return GL_RED;
430
431      case GL_RG16F:
432	 /* RG16F depends on both ARB_half_float_pixel and ARB_texture_float.
433	  */
434	 if (!ctx->Extensions.ARB_half_float_pixel)
435	    break;
436	 /* FALLTHROUGH */
437      case GL_RG32F:
438	 if (!ctx->Extensions.ARB_texture_float)
439	    break;
440         return GL_RG;
441      case GL_RG8I:
442      case GL_RG8UI:
443      case GL_RG16I:
444      case GL_RG16UI:
445      case GL_RG32I:
446      case GL_RG32UI:
447	 if (!ctx->Extensions.EXT_texture_integer)
448	    break;
449	 /* FALLTHROUGH */
450      case GL_RG:
451      case GL_RG8:
452      case GL_RG16:
453      case GL_COMPRESSED_RG:
454         return GL_RG;
455      default:
456         ; /* fallthrough */
457      }
458   }
459
460   if (ctx->Extensions.EXT_texture_shared_exponent) {
461      switch (internalFormat) {
462      case GL_RGB9_E5_EXT:
463         return GL_RGB;
464      default:
465         ; /* fallthrough */
466      }
467   }
468
469   if (ctx->Extensions.EXT_packed_float) {
470      switch (internalFormat) {
471      case GL_R11F_G11F_B10F_EXT:
472         return GL_RGB;
473      default:
474         ; /* fallthrough */
475      }
476   }
477
478   if (ctx->Extensions.ARB_depth_buffer_float) {
479      switch (internalFormat) {
480      case GL_DEPTH_COMPONENT32F:
481         return GL_DEPTH_COMPONENT;
482      case GL_DEPTH32F_STENCIL8:
483         return GL_DEPTH_STENCIL;
484      default:
485         ; /* fallthrough */
486      }
487   }
488
489   if (ctx->Extensions.ARB_texture_compression_rgtc) {
490      switch (internalFormat) {
491      case GL_COMPRESSED_RED_RGTC1:
492      case GL_COMPRESSED_SIGNED_RED_RGTC1:
493         return GL_RED;
494      case GL_COMPRESSED_RG_RGTC2:
495      case GL_COMPRESSED_SIGNED_RG_RGTC2:
496         return GL_RG;
497      default:
498         ; /* fallthrough */
499      }
500   }
501
502   return -1; /* error */
503}
504
505
506/**
507 * For cube map faces, return a face index in [0,5].
508 * For other targets return 0;
509 */
510GLuint
511_mesa_tex_target_to_face(GLenum target)
512{
513   if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
514       target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)
515      return (GLuint) target - (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X;
516   else
517      return 0;
518}
519
520
521
522/**
523 * Store a gl_texture_image pointer in a gl_texture_object structure
524 * according to the target and level parameters.
525 *
526 * \param tObj texture object.
527 * \param target texture target.
528 * \param level image level.
529 * \param texImage texture image.
530 *
531 * This was basically prompted by the introduction of cube maps.
532 */
533void
534_mesa_set_tex_image(struct gl_texture_object *tObj,
535                    GLenum target, GLint level,
536                    struct gl_texture_image *texImage)
537{
538   const GLuint face = _mesa_tex_target_to_face(target);
539
540   ASSERT(tObj);
541   ASSERT(texImage);
542   ASSERT(target != GL_TEXTURE_RECTANGLE_NV || level == 0);
543
544   tObj->Image[face][level] = texImage;
545
546   /* Set the 'back' pointer */
547   texImage->TexObject = tObj;
548}
549
550
551/**
552 * Allocate a texture image structure.
553 *
554 * Called via ctx->Driver.NewTextureImage() unless overriden by a device
555 * driver.
556 *
557 * \return a pointer to gl_texture_image struct with all fields initialized to
558 * zero.
559 */
560struct gl_texture_image *
561_mesa_new_texture_image( struct gl_context *ctx )
562{
563   (void) ctx;
564   return CALLOC_STRUCT(gl_texture_image);
565}
566
567
568/**
569 * Free texture image data.
570 * This function is a fallback called via ctx->Driver.FreeTexImageData().
571 *
572 * \param texImage texture image.
573 *
574 * Free the texture image data if it's not marked as client data.
575 */
576void
577_mesa_free_texture_image_data(struct gl_context *ctx,
578                              struct gl_texture_image *texImage)
579{
580   (void) ctx;
581
582   if (texImage->Data && !texImage->IsClientData) {
583      /* free the old texture data */
584      _mesa_free_texmemory(texImage->Data);
585   }
586
587   texImage->Data = NULL;
588}
589
590
591/**
592 * Free texture image.
593 *
594 * \param texImage texture image.
595 *
596 * Free the texture image structure and the associated image data.
597 */
598void
599_mesa_delete_texture_image(struct gl_context *ctx,
600                           struct gl_texture_image *texImage)
601{
602   /* Free texImage->Data and/or any other driver-specific texture
603    * image storage.
604    */
605   ASSERT(ctx->Driver.FreeTexImageData);
606   ctx->Driver.FreeTexImageData( ctx, texImage );
607
608   ASSERT(texImage->Data == NULL);
609   if (texImage->ImageOffsets)
610      free(texImage->ImageOffsets);
611   free(texImage);
612}
613
614
615/**
616 * Test if a target is a proxy target.
617 *
618 * \param target texture target.
619 *
620 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
621 */
622GLboolean
623_mesa_is_proxy_texture(GLenum target)
624{
625   /* NUM_TEXTURE_TARGETS should match number of terms below */
626   assert(NUM_TEXTURE_TARGETS == 7);
627
628   return (target == GL_PROXY_TEXTURE_1D ||
629           target == GL_PROXY_TEXTURE_2D ||
630           target == GL_PROXY_TEXTURE_3D ||
631           target == GL_PROXY_TEXTURE_CUBE_MAP_ARB ||
632           target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
633           target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
634           target == GL_PROXY_TEXTURE_2D_ARRAY_EXT);
635}
636
637
638/**
639 * Return the proxy target which corresponds to the given texture target
640 */
641static GLenum
642get_proxy_target(GLenum target)
643{
644   switch (target) {
645   case GL_TEXTURE_1D:
646   case GL_PROXY_TEXTURE_1D:
647      return GL_PROXY_TEXTURE_1D;
648   case GL_TEXTURE_2D:
649   case GL_PROXY_TEXTURE_2D:
650      return GL_PROXY_TEXTURE_2D;
651   case GL_TEXTURE_3D:
652   case GL_PROXY_TEXTURE_3D:
653      return GL_PROXY_TEXTURE_3D;
654   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
655   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
656   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
657   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
658   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
659   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
660   case GL_TEXTURE_CUBE_MAP_ARB:
661   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
662      return GL_PROXY_TEXTURE_CUBE_MAP_ARB;
663   case GL_TEXTURE_RECTANGLE_NV:
664   case GL_PROXY_TEXTURE_RECTANGLE_NV:
665      return GL_PROXY_TEXTURE_RECTANGLE_NV;
666   case GL_TEXTURE_1D_ARRAY_EXT:
667   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
668      return GL_PROXY_TEXTURE_1D_ARRAY_EXT;
669   case GL_TEXTURE_2D_ARRAY_EXT:
670   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
671      return GL_PROXY_TEXTURE_2D_ARRAY_EXT;
672   default:
673      _mesa_problem(NULL, "unexpected target in get_proxy_target()");
674      return 0;
675   }
676}
677
678
679/**
680 * Get the texture object that corresponds to the target of the given
681 * texture unit.
682 *
683 * \param ctx GL context.
684 * \param texUnit texture unit.
685 * \param target texture target.
686 *
687 * \return pointer to the texture object on success, or NULL on failure.
688 *
689 * \sa gl_texture_unit.
690 */
691struct gl_texture_object *
692_mesa_select_tex_object(struct gl_context *ctx,
693                        const struct gl_texture_unit *texUnit,
694                        GLenum target)
695{
696   switch (target) {
697      case GL_TEXTURE_1D:
698         return texUnit->CurrentTex[TEXTURE_1D_INDEX];
699      case GL_PROXY_TEXTURE_1D:
700         return ctx->Texture.ProxyTex[TEXTURE_1D_INDEX];
701      case GL_TEXTURE_2D:
702         return texUnit->CurrentTex[TEXTURE_2D_INDEX];
703      case GL_PROXY_TEXTURE_2D:
704         return ctx->Texture.ProxyTex[TEXTURE_2D_INDEX];
705      case GL_TEXTURE_3D:
706         return texUnit->CurrentTex[TEXTURE_3D_INDEX];
707      case GL_PROXY_TEXTURE_3D:
708         return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX];
709      case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
710      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
711      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
712      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
713      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
714      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
715      case GL_TEXTURE_CUBE_MAP_ARB:
716         return ctx->Extensions.ARB_texture_cube_map
717                ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL;
718      case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
719         return ctx->Extensions.ARB_texture_cube_map
720                ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL;
721      case GL_TEXTURE_RECTANGLE_NV:
722         return ctx->Extensions.NV_texture_rectangle
723                ? texUnit->CurrentTex[TEXTURE_RECT_INDEX] : NULL;
724      case GL_PROXY_TEXTURE_RECTANGLE_NV:
725         return ctx->Extensions.NV_texture_rectangle
726                ? ctx->Texture.ProxyTex[TEXTURE_RECT_INDEX] : NULL;
727      case GL_TEXTURE_1D_ARRAY_EXT:
728         return ctx->Extensions.MESA_texture_array
729                ? texUnit->CurrentTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
730      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
731         return ctx->Extensions.MESA_texture_array
732                ? ctx->Texture.ProxyTex[TEXTURE_1D_ARRAY_INDEX] : NULL;
733      case GL_TEXTURE_2D_ARRAY_EXT:
734         return ctx->Extensions.MESA_texture_array
735                ? texUnit->CurrentTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
736      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
737         return ctx->Extensions.MESA_texture_array
738                ? ctx->Texture.ProxyTex[TEXTURE_2D_ARRAY_INDEX] : NULL;
739      default:
740         _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
741         return NULL;
742   }
743}
744
745
746/**
747 * Return pointer to texture object for given target on current texture unit.
748 */
749struct gl_texture_object *
750_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target)
751{
752   struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
753   return _mesa_select_tex_object(ctx, texUnit, target);
754}
755
756
757/**
758 * Get a texture image pointer from a texture object, given a texture
759 * target and mipmap level.  The target and level parameters should
760 * have already been error-checked.
761 *
762 * \param ctx GL context.
763 * \param texObj texture unit.
764 * \param target texture target.
765 * \param level image level.
766 *
767 * \return pointer to the texture image structure, or NULL on failure.
768 */
769struct gl_texture_image *
770_mesa_select_tex_image(struct gl_context *ctx,
771                       const struct gl_texture_object *texObj,
772		       GLenum target, GLint level)
773{
774   const GLuint face = _mesa_tex_target_to_face(target);
775
776   ASSERT(texObj);
777   ASSERT(level >= 0);
778   ASSERT(level < MAX_TEXTURE_LEVELS);
779
780   return texObj->Image[face][level];
781}
782
783
784/**
785 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
786 * it and install it.  Only return NULL if passed a bad parameter or run
787 * out of memory.
788 */
789struct gl_texture_image *
790_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
791                    GLenum target, GLint level)
792{
793   struct gl_texture_image *texImage;
794
795   if (!texObj)
796      return NULL;
797
798   texImage = _mesa_select_tex_image(ctx, texObj, target, level);
799   if (!texImage) {
800      texImage = ctx->Driver.NewTextureImage(ctx);
801      if (!texImage) {
802         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
803         return NULL;
804      }
805
806      _mesa_set_tex_image(texObj, target, level, texImage);
807   }
808
809   return texImage;
810}
811
812
813/**
814 * Return pointer to the specified proxy texture image.
815 * Note that proxy textures are per-context, not per-texture unit.
816 * \return pointer to texture image or NULL if invalid target, invalid
817 *         level, or out of memory.
818 */
819struct gl_texture_image *
820_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
821{
822   struct gl_texture_image *texImage;
823   GLuint texIndex;
824
825   if (level < 0 )
826      return NULL;
827
828   switch (target) {
829   case GL_PROXY_TEXTURE_1D:
830      if (level >= ctx->Const.MaxTextureLevels)
831         return NULL;
832      texIndex = TEXTURE_1D_INDEX;
833      break;
834   case GL_PROXY_TEXTURE_2D:
835      if (level >= ctx->Const.MaxTextureLevels)
836         return NULL;
837      texIndex = TEXTURE_2D_INDEX;
838      break;
839   case GL_PROXY_TEXTURE_3D:
840      if (level >= ctx->Const.Max3DTextureLevels)
841         return NULL;
842      texIndex = TEXTURE_3D_INDEX;
843      break;
844   case GL_PROXY_TEXTURE_CUBE_MAP:
845      if (level >= ctx->Const.MaxCubeTextureLevels)
846         return NULL;
847      texIndex = TEXTURE_CUBE_INDEX;
848      break;
849   case GL_PROXY_TEXTURE_RECTANGLE_NV:
850      if (level > 0)
851         return NULL;
852      texIndex = TEXTURE_RECT_INDEX;
853      break;
854   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
855      if (level >= ctx->Const.MaxTextureLevels)
856         return NULL;
857      texIndex = TEXTURE_1D_ARRAY_INDEX;
858      break;
859   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
860      if (level >= ctx->Const.MaxTextureLevels)
861         return NULL;
862      texIndex = TEXTURE_2D_ARRAY_INDEX;
863      break;
864   default:
865      return NULL;
866   }
867
868   texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level];
869   if (!texImage) {
870      texImage = ctx->Driver.NewTextureImage(ctx);
871      if (!texImage) {
872         _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
873         return NULL;
874      }
875      ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage;
876      /* Set the 'back' pointer */
877      texImage->TexObject = ctx->Texture.ProxyTex[texIndex];
878   }
879   return texImage;
880}
881
882
883/**
884 * Get the maximum number of allowed mipmap levels.
885 *
886 * \param ctx GL context.
887 * \param target texture target.
888 *
889 * \return the maximum number of allowed mipmap levels for the given
890 * texture target, or zero if passed a bad target.
891 *
892 * \sa gl_constants.
893 */
894GLint
895_mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
896{
897   switch (target) {
898   case GL_TEXTURE_1D:
899   case GL_PROXY_TEXTURE_1D:
900   case GL_TEXTURE_2D:
901   case GL_PROXY_TEXTURE_2D:
902      return ctx->Const.MaxTextureLevels;
903   case GL_TEXTURE_3D:
904   case GL_PROXY_TEXTURE_3D:
905      return ctx->Const.Max3DTextureLevels;
906   case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
907   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
908   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
909   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
910   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
911   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
912   case GL_TEXTURE_CUBE_MAP_ARB:
913   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
914      return ctx->Extensions.ARB_texture_cube_map
915         ? ctx->Const.MaxCubeTextureLevels : 0;
916   case GL_TEXTURE_RECTANGLE_NV:
917   case GL_PROXY_TEXTURE_RECTANGLE_NV:
918      return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
919   case GL_TEXTURE_1D_ARRAY_EXT:
920   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
921   case GL_TEXTURE_2D_ARRAY_EXT:
922   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
923      return ctx->Extensions.MESA_texture_array
924         ? ctx->Const.MaxTextureLevels : 0;
925   default:
926      return 0; /* bad target */
927   }
928}
929
930
931/**
932 * Return number of dimensions per mipmap level for the given texture target.
933 */
934static GLint
935get_texture_dimensions(GLenum target)
936{
937   switch (target) {
938   case GL_TEXTURE_1D:
939   case GL_PROXY_TEXTURE_1D:
940      return 1;
941   case GL_TEXTURE_2D:
942   case GL_TEXTURE_RECTANGLE:
943   case GL_TEXTURE_CUBE_MAP:
944   case GL_PROXY_TEXTURE_2D:
945   case GL_PROXY_TEXTURE_RECTANGLE:
946   case GL_PROXY_TEXTURE_CUBE_MAP:
947   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
948   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
949   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
950   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
951   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
952   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
953   case GL_TEXTURE_1D_ARRAY:
954   case GL_PROXY_TEXTURE_1D_ARRAY:
955      return 2;
956   case GL_TEXTURE_3D:
957   case GL_PROXY_TEXTURE_3D:
958   case GL_TEXTURE_2D_ARRAY:
959   case GL_PROXY_TEXTURE_2D_ARRAY:
960      return 3;
961   default:
962      _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
963                    target);
964      return 2;
965   }
966}
967
968
969
970
971#if 000 /* not used anymore */
972/*
973 * glTexImage[123]D can accept a NULL image pointer.  In this case we
974 * create a texture image with unspecified image contents per the OpenGL
975 * spec.
976 */
977static GLubyte *
978make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
979{
980   const GLint components = _mesa_components_in_format(format);
981   const GLint numPixels = width * height * depth;
982   GLubyte *data = (GLubyte *) MALLOC(numPixels * components * sizeof(GLubyte));
983
984#ifdef DEBUG
985   /*
986    * Let's see if anyone finds this.  If glTexImage2D() is called with
987    * a NULL image pointer then load the texture image with something
988    * interesting instead of leaving it indeterminate.
989    */
990   if (data) {
991      static const char message[8][32] = {
992         "   X   X  XXXXX   XXX     X    ",
993         "   XX XX  X      X   X   X X   ",
994         "   X X X  X      X      X   X  ",
995         "   X   X  XXXX    XXX   XXXXX  ",
996         "   X   X  X          X  X   X  ",
997         "   X   X  X      X   X  X   X  ",
998         "   X   X  XXXXX   XXX   X   X  ",
999         "                               "
1000      };
1001
1002      GLubyte *imgPtr = data;
1003      GLint h, i, j, k;
1004      for (h = 0; h < depth; h++) {
1005         for (i = 0; i < height; i++) {
1006            GLint srcRow = 7 - (i % 8);
1007            for (j = 0; j < width; j++) {
1008               GLint srcCol = j % 32;
1009               GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
1010               for (k = 0; k < components; k++) {
1011                  *imgPtr++ = texel;
1012               }
1013            }
1014         }
1015      }
1016   }
1017#endif
1018
1019   return data;
1020}
1021#endif
1022
1023
1024
1025/**
1026 * Reset the fields of a gl_texture_image struct to zero.
1027 *
1028 * \param img texture image structure.
1029 *
1030 * This is called when a proxy texture test fails, we set all the
1031 * image members (except DriverData) to zero.
1032 * It's also used in glTexImage[123]D as a safeguard to be sure all
1033 * required fields get initialized properly by the Driver.TexImage[123]D
1034 * functions.
1035 */
1036static void
1037clear_teximage_fields(struct gl_texture_image *img)
1038{
1039   ASSERT(img);
1040   img->_BaseFormat = 0;
1041   img->InternalFormat = 0;
1042   img->Border = 0;
1043   img->Width = 0;
1044   img->Height = 0;
1045   img->Depth = 0;
1046   img->RowStride = 0;
1047   if (img->ImageOffsets) {
1048      free(img->ImageOffsets);
1049      img->ImageOffsets = NULL;
1050   }
1051   img->Width2 = 0;
1052   img->Height2 = 0;
1053   img->Depth2 = 0;
1054   img->WidthLog2 = 0;
1055   img->HeightLog2 = 0;
1056   img->DepthLog2 = 0;
1057   img->Data = NULL;
1058   img->TexFormat = MESA_FORMAT_NONE;
1059   img->FetchTexelc = NULL;
1060   img->FetchTexelf = NULL;
1061}
1062
1063
1064/**
1065 * Initialize basic fields of the gl_texture_image struct.
1066 *
1067 * \param ctx GL context.
1068 * \param target texture target (GL_TEXTURE_1D, GL_TEXTURE_RECTANGLE, etc).
1069 * \param img texture image structure to be initialized.
1070 * \param width image width.
1071 * \param height image height.
1072 * \param depth image depth.
1073 * \param border image border.
1074 * \param internalFormat internal format.
1075 * \param format  the actual hardware format (one of MESA_FORMAT_*)
1076 *
1077 * Fills in the fields of \p img with the given information.
1078 * Note: width, height and depth include the border.
1079 */
1080void
1081_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
1082                           struct gl_texture_image *img,
1083                           GLsizei width, GLsizei height, GLsizei depth,
1084                           GLint border, GLenum internalFormat,
1085                           gl_format format)
1086{
1087   GLint i, dims;
1088
1089   ASSERT(img);
1090   ASSERT(width >= 0);
1091   ASSERT(height >= 0);
1092   ASSERT(depth >= 0);
1093
1094   img->_BaseFormat = _mesa_base_tex_format( ctx, internalFormat );
1095   ASSERT(img->_BaseFormat > 0);
1096   img->InternalFormat = internalFormat;
1097   img->Border = border;
1098   img->Width = width;
1099   img->Height = height;
1100   img->Depth = depth;
1101
1102   img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
1103   img->WidthLog2 = logbase2(img->Width2);
1104
1105   if (height == 1) { /* 1-D texture */
1106      img->Height2 = 1;
1107      img->HeightLog2 = 0;
1108   }
1109   else {
1110      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
1111      img->HeightLog2 = logbase2(img->Height2);
1112   }
1113
1114   if (depth == 1) {  /* 2-D texture */
1115      img->Depth2 = 1;
1116      img->DepthLog2 = 0;
1117   }
1118   else {
1119      img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
1120      img->DepthLog2 = logbase2(img->Depth2);
1121   }
1122
1123   img->MaxLog2 = MAX2(img->WidthLog2, img->HeightLog2);
1124
1125   if ((width == 1 || _mesa_is_pow_two(img->Width2)) &&
1126       (height == 1 || _mesa_is_pow_two(img->Height2)) &&
1127       (depth == 1 || _mesa_is_pow_two(img->Depth2)))
1128      img->_IsPowerOfTwo = GL_TRUE;
1129   else
1130      img->_IsPowerOfTwo = GL_FALSE;
1131
1132   /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */
1133   img->RowStride = width;
1134   /* Allocate the ImageOffsets array and initialize to typical values.
1135    * We allocate the array for 1D/2D textures too in order to avoid special-
1136    * case code in the texstore routines.
1137    */
1138   if (img->ImageOffsets)
1139      free(img->ImageOffsets);
1140   img->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint));
1141   for (i = 0; i < depth; i++) {
1142      img->ImageOffsets[i] = i * width * height;
1143   }
1144
1145   /* Compute Width/Height/DepthScale for mipmap lod computation */
1146   if (target == GL_TEXTURE_RECTANGLE_NV) {
1147      /* scale = 1.0 since texture coords directly map to texels */
1148      img->WidthScale = 1.0;
1149      img->HeightScale = 1.0;
1150      img->DepthScale = 1.0;
1151   }
1152   else {
1153      img->WidthScale = (GLfloat) img->Width;
1154      img->HeightScale = (GLfloat) img->Height;
1155      img->DepthScale = (GLfloat) img->Depth;
1156   }
1157
1158   img->TexFormat = format;
1159
1160   dims = get_texture_dimensions(target);
1161
1162   _mesa_set_fetch_functions(img, dims);
1163}
1164
1165
1166/**
1167 * Free and clear fields of the gl_texture_image struct.
1168 *
1169 * \param ctx GL context.
1170 * \param texImage texture image structure to be cleared.
1171 *
1172 * After the call, \p texImage will have no data associated with it.  Its
1173 * fields are cleared so that its parent object will test incomplete.
1174 */
1175void
1176_mesa_clear_texture_image(struct gl_context *ctx,
1177                          struct gl_texture_image *texImage)
1178{
1179   ctx->Driver.FreeTexImageData(ctx, texImage);
1180   clear_teximage_fields(texImage);
1181}
1182
1183
1184/**
1185 * This is the fallback for Driver.TestProxyTexImage().  Test the texture
1186 * level, width, height and depth against the ctx->Const limits for textures.
1187 *
1188 * A hardware driver might override this function if, for example, the
1189 * max 3D texture size is 512x512x64 (i.e. not a cube).
1190 *
1191 * Note that width, height, depth == 0 is not an error.  However, a
1192 * texture with zero width/height/depth will be considered "incomplete"
1193 * and texturing will effectively be disabled.
1194 *
1195 * \param target  one of GL_PROXY_TEXTURE_1D, GL_PROXY_TEXTURE_2D,
1196 *                GL_PROXY_TEXTURE_3D, GL_PROXY_TEXTURE_RECTANGLE_NV,
1197 *                GL_PROXY_TEXTURE_CUBE_MAP_ARB.
1198 * \param level  as passed to glTexImage
1199 * \param internalFormat  as passed to glTexImage
1200 * \param format  as passed to glTexImage
1201 * \param type  as passed to glTexImage
1202 * \param width  as passed to glTexImage
1203 * \param height  as passed to glTexImage
1204 * \param depth  as passed to glTexImage
1205 * \param border  as passed to glTexImage
1206 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
1207 */
1208GLboolean
1209_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
1210                          GLint internalFormat, GLenum format, GLenum type,
1211                          GLint width, GLint height, GLint depth, GLint border)
1212{
1213   GLint maxSize;
1214
1215   (void) internalFormat;
1216   (void) format;
1217   (void) type;
1218
1219   switch (target) {
1220   case GL_PROXY_TEXTURE_1D:
1221      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
1222      if (width < 2 * border || width > 2 + maxSize ||
1223          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1224           width >0 && !_mesa_is_pow_two(width - 2 * border)) ||
1225          level >= ctx->Const.MaxTextureLevels) {
1226         /* bad width or level */
1227         return GL_FALSE;
1228      }
1229      return GL_TRUE;
1230   case GL_PROXY_TEXTURE_2D:
1231      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
1232      if (width < 2 * border || width > 2 + maxSize ||
1233          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1234           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
1235          height < 2 * border || height > 2 + maxSize ||
1236          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1237           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
1238          level >= ctx->Const.MaxTextureLevels) {
1239         /* bad width or height or level */
1240         return GL_FALSE;
1241      }
1242      return GL_TRUE;
1243   case GL_PROXY_TEXTURE_3D:
1244      maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
1245      if (width < 2 * border || width > 2 + maxSize ||
1246          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1247           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
1248          height < 2 * border || height > 2 + maxSize ||
1249          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1250           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
1251          depth < 2 * border || depth > 2 + maxSize ||
1252          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1253           depth > 0 && !_mesa_is_pow_two(depth - 2 * border)) ||
1254          level >= ctx->Const.Max3DTextureLevels) {
1255         /* bad width or height or depth or level */
1256         return GL_FALSE;
1257      }
1258      return GL_TRUE;
1259   case GL_PROXY_TEXTURE_RECTANGLE_NV:
1260      if (width < 0 || width > ctx->Const.MaxTextureRectSize ||
1261          height < 0 || height > ctx->Const.MaxTextureRectSize ||
1262          level != 0) {
1263         /* bad width or height or level */
1264         return GL_FALSE;
1265      }
1266      return GL_TRUE;
1267   case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
1268      maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
1269      if (width < 2 * border || width > 2 + maxSize ||
1270          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1271           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
1272          height < 2 * border || height > 2 + maxSize ||
1273          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1274           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
1275          level >= ctx->Const.MaxCubeTextureLevels) {
1276         /* bad width or height */
1277         return GL_FALSE;
1278      }
1279      return GL_TRUE;
1280   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1281      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
1282      if (width < 2 * border || width > 2 + maxSize ||
1283          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1284           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
1285          level >= ctx->Const.MaxTextureLevels) {
1286         /* bad width or level */
1287         return GL_FALSE;
1288      }
1289
1290      if (height < 1 || height > ctx->Const.MaxArrayTextureLayers) {
1291         return GL_FALSE;
1292      }
1293      return GL_TRUE;
1294   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1295      maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
1296      if (width < 2 * border || width > 2 + maxSize ||
1297          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1298           width > 0 && !_mesa_is_pow_two(width - 2 * border)) ||
1299          height < 2 * border || height > 2 + maxSize ||
1300          (!ctx->Extensions.ARB_texture_non_power_of_two &&
1301           height > 0 && !_mesa_is_pow_two(height - 2 * border)) ||
1302          level >= ctx->Const.MaxTextureLevels) {
1303         /* bad width or height or level */
1304         return GL_FALSE;
1305      }
1306      if (depth < 1 || depth > ctx->Const.MaxArrayTextureLayers) {
1307         return GL_FALSE;
1308      }
1309      return GL_TRUE;
1310   default:
1311      _mesa_problem(ctx, "Invalid target in _mesa_test_proxy_teximage");
1312      return GL_FALSE;
1313   }
1314}
1315
1316
1317/**
1318 * Check if the memory used by the texture would exceed the driver's limit.
1319 * This lets us support a max 3D texture size of 8K (for example) but
1320 * prevents allocating a full 8K x 8K x 8K texture.
1321 * XXX this could be rolled into the proxy texture size test (above) but
1322 * we don't have the actual texture internal format at that point.
1323 */
1324static GLboolean
1325legal_texture_size(struct gl_context *ctx, gl_format format,
1326                   GLint width, GLint height, GLint depth)
1327{
1328   uint64_t bytes = _mesa_format_image_size64(format, width, height, depth);
1329   uint64_t mbytes = bytes / (1024 * 1024); /* convert to MB */
1330   return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
1331}
1332
1333
1334
1335/**
1336 * Helper function to determine whether a target supports compressed textures
1337 */
1338static GLboolean
1339target_can_be_compressed(struct gl_context *ctx, GLenum target)
1340{
1341   switch (target) {
1342   case GL_TEXTURE_2D:
1343   case GL_PROXY_TEXTURE_2D:
1344      return GL_TRUE;
1345   case GL_PROXY_TEXTURE_CUBE_MAP:
1346   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1347   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1348   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1349   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1350   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1351   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1352      return ctx->Extensions.ARB_texture_cube_map;
1353   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1354   case GL_TEXTURE_2D_ARRAY_EXT:
1355      return ctx->Extensions.MESA_texture_array;
1356   default:
1357      return GL_FALSE;
1358   }
1359}
1360
1361
1362/**
1363 * Check if the given texture target value is legal for a
1364 * glTexImage1/2/3D call.
1365 */
1366static GLboolean
1367legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
1368{
1369   switch (dims) {
1370   case 1:
1371      switch (target) {
1372      case GL_TEXTURE_1D:
1373      case GL_PROXY_TEXTURE_1D:
1374         return GL_TRUE;
1375      default:
1376         return GL_FALSE;
1377      }
1378   case 2:
1379      switch (target) {
1380      case GL_TEXTURE_2D:
1381      case GL_PROXY_TEXTURE_2D:
1382         return GL_TRUE;
1383      case GL_PROXY_TEXTURE_CUBE_MAP:
1384      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1385      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1386      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1387      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1388      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1389      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1390         return ctx->Extensions.ARB_texture_cube_map;
1391      case GL_TEXTURE_RECTANGLE_NV:
1392      case GL_PROXY_TEXTURE_RECTANGLE_NV:
1393         return ctx->Extensions.NV_texture_rectangle;
1394      case GL_TEXTURE_1D_ARRAY_EXT:
1395      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1396         return ctx->Extensions.MESA_texture_array;
1397      default:
1398         return GL_FALSE;
1399      }
1400   case 3:
1401      switch (target) {
1402      case GL_TEXTURE_3D:
1403      case GL_PROXY_TEXTURE_3D:
1404         return GL_TRUE;
1405      case GL_TEXTURE_2D_ARRAY_EXT:
1406      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1407         return ctx->Extensions.MESA_texture_array;
1408      default:
1409         return GL_FALSE;
1410      }
1411   default:
1412      _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
1413      return GL_FALSE;
1414   }
1415}
1416
1417
1418/**
1419 * Check if the given texture target value is legal for a
1420 * glCopyTexImage1/2D call.
1421 */
1422static GLboolean
1423legal_copyteximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
1424{
1425   switch (dims) {
1426   case 1:
1427      return target == GL_TEXTURE_1D;
1428   case 2:
1429      switch (target) {
1430      case GL_TEXTURE_2D:
1431         return GL_TRUE;
1432      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1433      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1434      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1435      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1436      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1437      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1438         return ctx->Extensions.ARB_texture_cube_map;
1439      case GL_TEXTURE_RECTANGLE_NV:
1440         return ctx->Extensions.NV_texture_rectangle;
1441      case GL_TEXTURE_1D_ARRAY_EXT:
1442         return ctx->Extensions.MESA_texture_array;
1443      default:
1444         return GL_FALSE;
1445      }
1446   default:
1447      _mesa_problem(ctx, "invalid dims=%u in legal_copyteximage_target()", dims);
1448      return GL_FALSE;
1449   }
1450}
1451
1452
1453/**
1454 * Check if the given texture target value is legal for a
1455 * glCompressedTexImage1/2/3D call.
1456 */
1457static GLboolean
1458legal_compressed_teximage_target(struct gl_context *ctx, GLuint dims,
1459                                 GLenum target)
1460{
1461   switch (dims) {
1462   case 1:
1463      return GL_FALSE;  /* No 1D compresssed textures yet */
1464   case 2:
1465      switch (target) {
1466      case GL_TEXTURE_2D:
1467      case GL_PROXY_TEXTURE_2D:
1468         return GL_TRUE;
1469      case GL_PROXY_TEXTURE_CUBE_MAP:
1470      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1471      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1472      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1473      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1474      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1475      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1476         return ctx->Extensions.ARB_texture_cube_map;
1477      case GL_TEXTURE_RECTANGLE_NV:
1478      case GL_PROXY_TEXTURE_RECTANGLE_NV:
1479         return GL_FALSE; /* not supported yet */
1480      case GL_TEXTURE_1D_ARRAY_EXT:
1481      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1482         return GL_FALSE; /* not supported yet */
1483      default:
1484         return GL_FALSE;
1485      }
1486   case 3:
1487      return GL_FALSE;  /* No 3D compressed textures yet */
1488   default:
1489      _mesa_problem(ctx,
1490                    "invalid dims=%u in legal_compressed_teximage_target()",
1491                    dims);
1492      return GL_FALSE;
1493   }
1494}
1495
1496
1497
1498/**
1499 * Test the glTexImage[123]D() parameters for errors.
1500 *
1501 * \param ctx GL context.
1502 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1503 * \param target texture target given by the user.
1504 * \param level image level given by the user.
1505 * \param internalFormat internal format given by the user.
1506 * \param format pixel data format given by the user.
1507 * \param type pixel data type given by the user.
1508 * \param width image width given by the user.
1509 * \param height image height given by the user.
1510 * \param depth image depth given by the user.
1511 * \param border image border given by the user.
1512 *
1513 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1514 *
1515 * Verifies each of the parameters against the constants specified in
1516 * __struct gl_contextRec::Const and the supported extensions, and according
1517 * to the OpenGL specification.
1518 */
1519static GLboolean
1520texture_error_check( struct gl_context *ctx,
1521                     GLuint dimensions, GLenum target,
1522                     GLint level, GLint internalFormat,
1523                     GLenum format, GLenum type,
1524                     GLint width, GLint height,
1525                     GLint depth, GLint border )
1526{
1527   const GLenum proxyTarget = get_proxy_target(target);
1528   const GLboolean isProxy = target == proxyTarget;
1529   GLboolean sizeOK = GL_TRUE;
1530   GLboolean colorFormat, indexFormat;
1531
1532   /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1533   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1534      if (!isProxy) {
1535         _mesa_error(ctx, GL_INVALID_VALUE,
1536                     "glTexImage%dD(level=%d)", dimensions, level);
1537      }
1538      return GL_TRUE;
1539   }
1540
1541   /* Check border */
1542   if (border < 0 || border > 1 ||
1543       ((target == GL_TEXTURE_RECTANGLE_NV ||
1544         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
1545      if (!isProxy) {
1546         _mesa_error(ctx, GL_INVALID_VALUE,
1547                     "glTexImage%dD(border=%d)", dimensions, border);
1548      }
1549      return GL_TRUE;
1550   }
1551
1552   if (width < 0 || height < 0 || depth < 0) {
1553      if (!isProxy) {
1554         _mesa_error(ctx, GL_INVALID_VALUE,
1555                     "glTexImage%dD(width, height or depth < 0)", dimensions);
1556      }
1557      return GL_TRUE;
1558   }
1559
1560   /* Do this simple check before calling the TestProxyTexImage() function */
1561   if (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
1562      sizeOK = (width == height);
1563   }
1564
1565   /*
1566    * Use the proxy texture driver hook to see if the size/level/etc are
1567    * legal.
1568    */
1569   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
1570                                                    internalFormat, format,
1571                                                    type, width, height,
1572                                                    depth, border);
1573   if (!sizeOK) {
1574      if (!isProxy) {
1575         _mesa_error(ctx, GL_INVALID_VALUE,
1576                     "glTexImage%dD(level=%d, width=%d, height=%d, depth=%d)",
1577                     dimensions, level, width, height, depth);
1578      }
1579      return GL_TRUE;
1580   }
1581
1582   /* Check internalFormat */
1583   if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
1584      if (!isProxy) {
1585         _mesa_error(ctx, GL_INVALID_VALUE,
1586                     "glTexImage%dD(internalFormat=%s)",
1587                     dimensions, _mesa_lookup_enum_by_nr(internalFormat));
1588      }
1589      return GL_TRUE;
1590   }
1591
1592   /* Check incoming image format and type */
1593   if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
1594      /* Normally, GL_INVALID_OPERATION is generated by a format/type
1595       * mismatch (see the 1.2 spec page 94, sec 3.6.4.).  But with the
1596       * GL_EXT_texture_integer extension, some combinations should generate
1597       * GL_INVALID_ENUM instead (grr!).
1598       */
1599      if (!isProxy) {
1600         GLenum error = _mesa_is_integer_format(format)
1601            ? GL_INVALID_ENUM : GL_INVALID_OPERATION;
1602         _mesa_error(ctx, error,
1603                     "glTexImage%dD(incompatible format 0x%x, type 0x%x)",
1604                     dimensions, format, type);
1605      }
1606      return GL_TRUE;
1607   }
1608
1609   /* make sure internal format and format basically agree */
1610   colorFormat = _mesa_is_color_format(format);
1611   indexFormat = _mesa_is_index_format(format);
1612   if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
1613       (_mesa_is_index_format(internalFormat) && !indexFormat) ||
1614       (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
1615       (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
1616       (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
1617       (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
1618      if (!isProxy)
1619         _mesa_error(ctx, GL_INVALID_OPERATION,
1620                     "glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
1621                     dimensions, internalFormat, format);
1622      return GL_TRUE;
1623   }
1624
1625   /* additional checks for ycbcr textures */
1626   if (internalFormat == GL_YCBCR_MESA) {
1627      ASSERT(ctx->Extensions.MESA_ycbcr_texture);
1628      if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
1629          type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
1630         char message[100];
1631         _mesa_snprintf(message, sizeof(message),
1632                        "glTexImage%dD(format/type YCBCR mismatch", dimensions);
1633         _mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
1634         return GL_TRUE; /* error */
1635      }
1636      if (target != GL_TEXTURE_2D &&
1637          target != GL_PROXY_TEXTURE_2D &&
1638          target != GL_TEXTURE_RECTANGLE_NV &&
1639          target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
1640         if (!isProxy)
1641            _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target)");
1642         return GL_TRUE;
1643      }
1644      if (border != 0) {
1645         if (!isProxy) {
1646            char message[100];
1647            _mesa_snprintf(message, sizeof(message),
1648                           "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
1649                           dimensions, border);
1650            _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
1651         }
1652         return GL_TRUE;
1653      }
1654   }
1655
1656   /* additional checks for depth textures */
1657   if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT) {
1658      /* Only 1D, 2D and rectangular textures supported, not 3D or cubes */
1659      if (target != GL_TEXTURE_1D &&
1660          target != GL_PROXY_TEXTURE_1D &&
1661          target != GL_TEXTURE_2D &&
1662          target != GL_PROXY_TEXTURE_2D &&
1663          target != GL_TEXTURE_RECTANGLE_ARB &&
1664          target != GL_PROXY_TEXTURE_RECTANGLE_ARB) {
1665         if (!isProxy)
1666            _mesa_error(ctx, GL_INVALID_ENUM,
1667                        "glTexImage(target/internalFormat)");
1668         return GL_TRUE;
1669      }
1670   }
1671
1672   /* additional checks for compressed textures */
1673   if (_mesa_is_compressed_format(ctx, internalFormat)) {
1674      if (!target_can_be_compressed(ctx, target) && !isProxy) {
1675         _mesa_error(ctx, GL_INVALID_ENUM,
1676                     "glTexImage%dD(target)", dimensions);
1677         return GL_TRUE;
1678      }
1679      if (border != 0) {
1680         if (!isProxy) {
1681            _mesa_error(ctx, GL_INVALID_OPERATION,
1682                        "glTexImage%dD(border!=0)", dimensions);
1683         }
1684         return GL_TRUE;
1685      }
1686   }
1687
1688   /* additional checks for integer textures */
1689   if (ctx->Extensions.EXT_texture_integer &&
1690       (_mesa_is_integer_format(format) !=
1691        _mesa_is_integer_format(internalFormat))) {
1692      if (!isProxy) {
1693         _mesa_error(ctx, GL_INVALID_OPERATION,
1694                     "glTexImage%dD(integer/non-integer format mismatch)",
1695                     dimensions);
1696      }
1697      return GL_TRUE;
1698   }
1699
1700   /* if we get here, the parameters are OK */
1701   return GL_FALSE;
1702}
1703
1704
1705/**
1706 * Test glTexSubImage[123]D() parameters for errors.
1707 *
1708 * \param ctx GL context.
1709 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1710 * \param target texture target given by the user.
1711 * \param level image level given by the user.
1712 * \param xoffset sub-image x offset given by the user.
1713 * \param yoffset sub-image y offset given by the user.
1714 * \param zoffset sub-image z offset given by the user.
1715 * \param format pixel data format given by the user.
1716 * \param type pixel data type given by the user.
1717 * \param width image width given by the user.
1718 * \param height image height given by the user.
1719 * \param depth image depth given by the user.
1720 *
1721 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1722 *
1723 * Verifies each of the parameters against the constants specified in
1724 * __struct gl_contextRec::Const and the supported extensions, and according
1725 * to the OpenGL specification.
1726 */
1727static GLboolean
1728subtexture_error_check( struct gl_context *ctx, GLuint dimensions,
1729                        GLenum target, GLint level,
1730                        GLint xoffset, GLint yoffset, GLint zoffset,
1731                        GLint width, GLint height, GLint depth,
1732                        GLenum format, GLenum type )
1733{
1734   /* Basic level check */
1735   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1736      _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage2D(level=%d)", level);
1737      return GL_TRUE;
1738   }
1739
1740   /* Check for negative sizes */
1741   if (width < 0) {
1742      _mesa_error(ctx, GL_INVALID_VALUE,
1743                  "glTexSubImage%dD(width=%d)", dimensions, width);
1744      return GL_TRUE;
1745   }
1746   if (height < 0 && dimensions > 1) {
1747      _mesa_error(ctx, GL_INVALID_VALUE,
1748                  "glTexSubImage%dD(height=%d)", dimensions, height);
1749      return GL_TRUE;
1750   }
1751   if (depth < 0 && dimensions > 2) {
1752      _mesa_error(ctx, GL_INVALID_VALUE,
1753                  "glTexSubImage%dD(depth=%d)", dimensions, depth);
1754      return GL_TRUE;
1755   }
1756
1757   if (!_mesa_is_legal_format_and_type(ctx, format, type)) {
1758      /* As with the glTexImage2D check above, the error code here
1759       * depends on texture integer.
1760       */
1761      GLenum error = _mesa_is_integer_format(format)
1762         ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
1763      _mesa_error(ctx, error,
1764                  "glTexSubImage%dD(incompatible format 0x%x, type 0x%x)",
1765                  dimensions, format, type);
1766      return GL_TRUE;
1767   }
1768
1769   return GL_FALSE;
1770}
1771
1772
1773/**
1774 * Do second part of glTexSubImage which depends on the destination texture.
1775 * \return GL_TRUE if error recorded, GL_FALSE otherwise
1776 */
1777static GLboolean
1778subtexture_error_check2( struct gl_context *ctx, GLuint dimensions,
1779			 GLenum target, GLint level,
1780			 GLint xoffset, GLint yoffset, GLint zoffset,
1781			 GLint width, GLint height, GLint depth,
1782			 GLenum format, GLenum type,
1783			 const struct gl_texture_image *destTex )
1784{
1785   if (!destTex) {
1786      /* undefined image level */
1787      _mesa_error(ctx, GL_INVALID_OPERATION, "glTexSubImage%dD", dimensions);
1788      return GL_TRUE;
1789   }
1790
1791   if (xoffset < -((GLint)destTex->Border)) {
1792      _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset)",
1793                  dimensions);
1794      return GL_TRUE;
1795   }
1796   if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
1797      _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(xoffset+width)",
1798                  dimensions);
1799      return GL_TRUE;
1800   }
1801   if (dimensions > 1) {
1802      if (yoffset < -((GLint)destTex->Border)) {
1803         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset)",
1804                     dimensions);
1805         return GL_TRUE;
1806      }
1807      if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
1808         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage%dD(yoffset+height)",
1809                     dimensions);
1810         return GL_TRUE;
1811      }
1812   }
1813   if (dimensions > 2) {
1814      if (zoffset < -((GLint)destTex->Border)) {
1815         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset)");
1816         return GL_TRUE;
1817      }
1818      if (zoffset + depth  > (GLint) (destTex->Depth + destTex->Border)) {
1819         _mesa_error(ctx, GL_INVALID_VALUE, "glTexSubImage3D(zoffset+depth)");
1820         return GL_TRUE;
1821      }
1822   }
1823
1824   if (_mesa_is_format_compressed(destTex->TexFormat)) {
1825      GLuint bw, bh;
1826
1827      if (!target_can_be_compressed(ctx, target)) {
1828         _mesa_error(ctx, GL_INVALID_ENUM,
1829                     "glTexSubImage%dD(target=%s)", dimensions,
1830                     _mesa_lookup_enum_by_nr(target));
1831         return GL_TRUE;
1832      }
1833
1834      /* do tests which depend on compression block size */
1835      _mesa_get_format_block_size(destTex->TexFormat, &bw, &bh);
1836
1837      /* offset must be multiple of block size */
1838      if ((xoffset % bw != 0) || (yoffset % bh != 0)) {
1839         _mesa_error(ctx, GL_INVALID_OPERATION,
1840                     "glTexSubImage%dD(xoffset = %d, yoffset = %d)",
1841                     dimensions, xoffset, yoffset);
1842         return GL_TRUE;
1843      }
1844      /* size must be multiple of bw by bh or equal to whole texture size */
1845      if ((width % bw != 0) && (GLuint) width != destTex->Width) {
1846         _mesa_error(ctx, GL_INVALID_OPERATION,
1847                     "glTexSubImage%dD(width = %d)", dimensions, width);
1848         return GL_TRUE;
1849      }
1850      if ((height % bh != 0) && (GLuint) height != destTex->Height) {
1851         _mesa_error(ctx, GL_INVALID_OPERATION,
1852                     "glTexSubImage%dD(height = %d)", dimensions, height);
1853         return GL_TRUE;
1854      }
1855   }
1856
1857   return GL_FALSE;
1858}
1859
1860
1861/**
1862 * Test glCopyTexImage[12]D() parameters for errors.
1863 *
1864 * \param ctx GL context.
1865 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1866 * \param target texture target given by the user.
1867 * \param level image level given by the user.
1868 * \param internalFormat internal format given by the user.
1869 * \param width image width given by the user.
1870 * \param height image height given by the user.
1871 * \param border texture border.
1872 *
1873 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
1874 *
1875 * Verifies each of the parameters against the constants specified in
1876 * __struct gl_contextRec::Const and the supported extensions, and according
1877 * to the OpenGL specification.
1878 */
1879static GLboolean
1880copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
1881                         GLenum target, GLint level, GLint internalFormat,
1882                         GLint width, GLint height, GLint border )
1883{
1884   const GLenum proxyTarget = get_proxy_target(target);
1885   const GLenum type = GL_FLOAT;
1886   GLboolean sizeOK;
1887   GLint format;
1888
1889   /* check target */
1890   if (!legal_copyteximage_target(ctx, dimensions, target)) {
1891      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
1892                  dimensions, _mesa_lookup_enum_by_nr(target));
1893      return GL_TRUE;
1894   }
1895
1896   /* Basic level check (more checking in ctx->Driver.TestProxyTexImage) */
1897   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
1898      _mesa_error(ctx, GL_INVALID_VALUE,
1899                  "glCopyTexImage%dD(level=%d)", dimensions, level);
1900      return GL_TRUE;
1901   }
1902
1903   /* Check that the source buffer is complete */
1904   if (ctx->ReadBuffer->Name) {
1905      _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
1906      if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
1907         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
1908                     "glCopyTexImage%dD(invalid readbuffer)", dimensions);
1909         return GL_TRUE;
1910      }
1911   }
1912
1913   /* Check border */
1914   if (border < 0 || border > 1 ||
1915       ((target == GL_TEXTURE_RECTANGLE_NV ||
1916         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
1917      return GL_TRUE;
1918   }
1919
1920   format = _mesa_base_tex_format(ctx, internalFormat);
1921   if (format < 0) {
1922      _mesa_error(ctx, GL_INVALID_VALUE,
1923                  "glCopyTexImage%dD(internalFormat)", dimensions);
1924      return GL_TRUE;
1925   }
1926
1927   if (!_mesa_source_buffer_exists(ctx, format)) {
1928      _mesa_error(ctx, GL_INVALID_OPERATION,
1929                  "glCopyTexImage%dD(missing readbuffer)", dimensions);
1930      return GL_TRUE;
1931   }
1932
1933   /* Do size, level checking */
1934   sizeOK = (proxyTarget == GL_PROXY_TEXTURE_CUBE_MAP_ARB)
1935      ? (width == height) : 1;
1936
1937   sizeOK = sizeOK && ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
1938                                                    internalFormat, format,
1939                                                    type, width, height,
1940                                                    1, border);
1941
1942   if (!sizeOK) {
1943      if (dimensions == 1) {
1944         _mesa_error(ctx, GL_INVALID_VALUE,
1945                     "glCopyTexImage1D(width=%d)", width);
1946      }
1947      else {
1948         ASSERT(dimensions == 2);
1949         _mesa_error(ctx, GL_INVALID_VALUE,
1950                     "glCopyTexImage2D(width=%d, height=%d)", width, height);
1951      }
1952      return GL_TRUE;
1953   }
1954
1955   if (_mesa_is_compressed_format(ctx, internalFormat)) {
1956      if (!target_can_be_compressed(ctx, target)) {
1957         _mesa_error(ctx, GL_INVALID_ENUM,
1958                     "glCopyTexImage%dD(target)", dimensions);
1959         return GL_TRUE;
1960      }
1961      if (border != 0) {
1962         _mesa_error(ctx, GL_INVALID_OPERATION,
1963                     "glCopyTexImage%dD(border!=0)", dimensions);
1964         return GL_TRUE;
1965      }
1966   }
1967   else if (_mesa_is_depth_format(internalFormat)) {
1968      /* make sure we have depth/stencil buffers */
1969      if (!ctx->ReadBuffer->_DepthBuffer) {
1970         _mesa_error(ctx, GL_INVALID_OPERATION,
1971                     "glCopyTexImage%dD(no depth)", dimensions);
1972         return GL_TRUE;
1973      }
1974   }
1975   else if (_mesa_is_depthstencil_format(internalFormat)) {
1976      /* make sure we have depth/stencil buffers */
1977      if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
1978         _mesa_error(ctx, GL_INVALID_OPERATION,
1979                     "glCopyTexImage%dD(no depth/stencil buffer)", dimensions);
1980         return GL_TRUE;
1981      }
1982   }
1983
1984   /* if we get here, the parameters are OK */
1985   return GL_FALSE;
1986}
1987
1988
1989/**
1990 * Test glCopyTexSubImage[12]D() parameters for errors.
1991 * Note that this is the first part of error checking.
1992 * See also copytexsubimage_error_check2() below for the second part.
1993 *
1994 * \param ctx GL context.
1995 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1996 * \param target texture target given by the user.
1997 * \param level image level given by the user.
1998 *
1999 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2000 */
2001static GLboolean
2002copytexsubimage_error_check1( struct gl_context *ctx, GLuint dimensions,
2003                              GLenum target, GLint level)
2004{
2005   /* Check that the source buffer is complete */
2006   if (ctx->ReadBuffer->Name) {
2007      _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2008      if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2009         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2010                     "glCopyTexImage%dD(invalid readbuffer)", dimensions);
2011         return GL_TRUE;
2012      }
2013   }
2014
2015   /* check target (proxies not allowed) */
2016   if (!legal_teximage_target(ctx, dimensions, target) ||
2017       _mesa_is_proxy_texture(target)) {
2018      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexSubImage%uD(target=%s)",
2019                  dimensions, _mesa_lookup_enum_by_nr(target));
2020      return GL_TRUE;
2021   }
2022
2023   /* Check level */
2024   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
2025      _mesa_error(ctx, GL_INVALID_VALUE,
2026                  "glCopyTexSubImage%dD(level=%d)", dimensions, level);
2027      return GL_TRUE;
2028   }
2029
2030   return GL_FALSE;
2031}
2032
2033
2034/**
2035 * Second part of error checking for glCopyTexSubImage[12]D().
2036 * \param xoffset sub-image x offset given by the user.
2037 * \param yoffset sub-image y offset given by the user.
2038 * \param zoffset sub-image z offset given by the user.
2039 * \param width image width given by the user.
2040 * \param height image height given by the user.
2041 */
2042static GLboolean
2043copytexsubimage_error_check2( struct gl_context *ctx, GLuint dimensions,
2044			      GLenum target, GLint level,
2045			      GLint xoffset, GLint yoffset, GLint zoffset,
2046			      GLsizei width, GLsizei height,
2047			      const struct gl_texture_image *teximage )
2048{
2049   /* check that dest tex image exists */
2050   if (!teximage) {
2051      _mesa_error(ctx, GL_INVALID_OPERATION,
2052                  "glCopyTexSubImage%dD(undefined texture level: %d)",
2053                  dimensions, level);
2054      return GL_TRUE;
2055   }
2056
2057   /* Check size */
2058   if (width < 0) {
2059      _mesa_error(ctx, GL_INVALID_VALUE,
2060                  "glCopyTexSubImage%dD(width=%d)", dimensions, width);
2061      return GL_TRUE;
2062   }
2063   if (dimensions > 1 && height < 0) {
2064      _mesa_error(ctx, GL_INVALID_VALUE,
2065                  "glCopyTexSubImage%dD(height=%d)", dimensions, height);
2066      return GL_TRUE;
2067   }
2068
2069   /* check x/y offsets */
2070   if (xoffset < -((GLint)teximage->Border)) {
2071      _mesa_error(ctx, GL_INVALID_VALUE,
2072                  "glCopyTexSubImage%dD(xoffset=%d)", dimensions, xoffset);
2073      return GL_TRUE;
2074   }
2075   if (xoffset + width > (GLint) (teximage->Width + teximage->Border)) {
2076      _mesa_error(ctx, GL_INVALID_VALUE,
2077                  "glCopyTexSubImage%dD(xoffset+width)", dimensions);
2078      return GL_TRUE;
2079   }
2080   if (dimensions > 1) {
2081      if (yoffset < -((GLint)teximage->Border)) {
2082         _mesa_error(ctx, GL_INVALID_VALUE,
2083                     "glCopyTexSubImage%dD(yoffset=%d)", dimensions, yoffset);
2084         return GL_TRUE;
2085      }
2086      /* NOTE: we're adding the border here, not subtracting! */
2087      if (yoffset + height > (GLint) (teximage->Height + teximage->Border)) {
2088         _mesa_error(ctx, GL_INVALID_VALUE,
2089                     "glCopyTexSubImage%dD(yoffset+height)", dimensions);
2090         return GL_TRUE;
2091      }
2092   }
2093
2094   /* check z offset */
2095   if (dimensions > 2) {
2096      if (zoffset < -((GLint)teximage->Border)) {
2097         _mesa_error(ctx, GL_INVALID_VALUE,
2098                     "glCopyTexSubImage%dD(zoffset)", dimensions);
2099         return GL_TRUE;
2100      }
2101      if (zoffset > (GLint) (teximage->Depth + teximage->Border)) {
2102         _mesa_error(ctx, GL_INVALID_VALUE,
2103                     "glCopyTexSubImage%dD(zoffset+depth)", dimensions);
2104         return GL_TRUE;
2105      }
2106   }
2107
2108   if (_mesa_is_format_compressed(teximage->TexFormat)) {
2109      if (!target_can_be_compressed(ctx, target)) {
2110         _mesa_error(ctx, GL_INVALID_ENUM,
2111                     "glCopyTexSubImage%dD(target)", dimensions);
2112         return GL_TRUE;
2113      }
2114      /* offset must be multiple of 4 */
2115      if ((xoffset & 3) || (yoffset & 3)) {
2116         _mesa_error(ctx, GL_INVALID_VALUE,
2117                     "glCopyTexSubImage%dD(xoffset or yoffset)", dimensions);
2118         return GL_TRUE;
2119      }
2120      /* size must be multiple of 4 */
2121      if ((width & 3) != 0 && (GLuint) width != teximage->Width) {
2122         _mesa_error(ctx, GL_INVALID_VALUE,
2123                     "glCopyTexSubImage%dD(width)", dimensions);
2124         return GL_TRUE;
2125      }
2126      if ((height & 3) != 0 && (GLuint) height != teximage->Height) {
2127         _mesa_error(ctx, GL_INVALID_VALUE,
2128                     "glCopyTexSubImage%dD(height)", dimensions);
2129         return GL_TRUE;
2130      }
2131   }
2132
2133   if (teximage->InternalFormat == GL_YCBCR_MESA) {
2134      _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D");
2135      return GL_TRUE;
2136   }
2137
2138   if (!_mesa_source_buffer_exists(ctx, teximage->_BaseFormat)) {
2139      _mesa_error(ctx, GL_INVALID_OPERATION,
2140                  "glCopyTexSubImage%dD(missing readbuffer, format=0x%x)",
2141                  dimensions, teximage->_BaseFormat);
2142      return GL_TRUE;
2143   }
2144
2145   if (teximage->_BaseFormat == GL_DEPTH_COMPONENT) {
2146      if (!ctx->ReadBuffer->_DepthBuffer) {
2147         _mesa_error(ctx, GL_INVALID_OPERATION,
2148                     "glCopyTexSubImage%dD(no depth buffer)",
2149                     dimensions);
2150         return GL_TRUE;
2151      }
2152   }
2153   else if (teximage->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
2154      if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
2155         _mesa_error(ctx, GL_INVALID_OPERATION,
2156                     "glCopyTexSubImage%dD(no depth/stencil buffer)",
2157                     dimensions);
2158         return GL_TRUE;
2159      }
2160   }
2161
2162   /* If copying into an integer texture, the source buffer must also be
2163    * integer-valued.
2164    */
2165   if (_mesa_is_format_integer_color(teximage->TexFormat)) {
2166      struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
2167      if (!_mesa_is_format_integer_color(rb->Format)) {
2168         _mesa_error(ctx, GL_INVALID_OPERATION,
2169                  "glCopyTexSubImage%dD(source buffer is not integer format)",
2170                  dimensions);
2171         return GL_TRUE;
2172      }
2173   }
2174
2175   /* if we get here, the parameters are OK */
2176   return GL_FALSE;
2177}
2178
2179
2180/** Callback info for walking over FBO hash table */
2181struct cb_info
2182{
2183   struct gl_context *ctx;
2184   struct gl_texture_object *texObj;
2185   GLuint level, face;
2186};
2187
2188
2189/**
2190 * Check render to texture callback.  Called from _mesa_HashWalk().
2191 */
2192static void
2193check_rtt_cb(GLuint key, void *data, void *userData)
2194{
2195   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2196   const struct cb_info *info = (struct cb_info *) userData;
2197   struct gl_context *ctx = info->ctx;
2198   const struct gl_texture_object *texObj = info->texObj;
2199   const GLuint level = info->level, face = info->face;
2200
2201   /* If this is a user-created FBO */
2202   if (fb->Name) {
2203      GLuint i;
2204      /* check if any of the FBO's attachments point to 'texObj' */
2205      for (i = 0; i < BUFFER_COUNT; i++) {
2206         struct gl_renderbuffer_attachment *att = fb->Attachment + i;
2207         if (att->Type == GL_TEXTURE &&
2208             att->Texture == texObj &&
2209             att->TextureLevel == level &&
2210             att->CubeMapFace == face) {
2211            ASSERT(att->Texture->Image[att->CubeMapFace][att->TextureLevel]);
2212            /* Tell driver about the new renderbuffer texture */
2213            ctx->Driver.RenderTexture(ctx, ctx->DrawBuffer, att);
2214            /* Mark fb status as indeterminate to force re-validation */
2215            fb->_Status = 0;
2216         }
2217      }
2218   }
2219}
2220
2221
2222/**
2223 * When a texture image is specified we have to check if it's bound to
2224 * any framebuffer objects (render to texture) in order to detect changes
2225 * in size or format since that effects FBO completeness.
2226 * Any FBOs rendering into the texture must be re-validated.
2227 */
2228static void
2229update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj,
2230                   GLuint face, GLuint level)
2231{
2232   /* Only check this texture if it's been marked as RenderToTexture */
2233   if (texObj->_RenderToTexture) {
2234      struct cb_info info;
2235      info.ctx = ctx;
2236      info.texObj = texObj;
2237      info.level = level;
2238      info.face = face;
2239      _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info);
2240   }
2241}
2242
2243
2244/**
2245 * If the texture object's GenerateMipmap flag is set and we've
2246 * changed the texture base level image, regenerate the rest of the
2247 * mipmap levels now.
2248 */
2249static INLINE void
2250check_gen_mipmap(struct gl_context *ctx, GLenum target,
2251                 struct gl_texture_object *texObj, GLint level)
2252{
2253   ASSERT(target != GL_TEXTURE_CUBE_MAP);
2254   if (texObj->GenerateMipmap &&
2255       level == texObj->BaseLevel &&
2256       level < texObj->MaxLevel) {
2257      ASSERT(ctx->Driver.GenerateMipmap);
2258      ctx->Driver.GenerateMipmap(ctx, target, texObj);
2259   }
2260}
2261
2262
2263/** Debug helper: override the user-requested internal format */
2264static GLenum
2265override_internal_format(GLenum internalFormat, GLint width, GLint height)
2266{
2267#if 0
2268   if (internalFormat == GL_RGBA16F_ARB ||
2269       internalFormat == GL_RGBA32F_ARB) {
2270      printf("Convert rgba float tex to int %d x %d\n", width, height);
2271      return GL_RGBA;
2272   }
2273   else if (internalFormat == GL_RGB16F_ARB ||
2274            internalFormat == GL_RGB32F_ARB) {
2275      printf("Convert rgb float tex to int %d x %d\n", width, height);
2276      return GL_RGB;
2277   }
2278   else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB ||
2279            internalFormat == GL_LUMINANCE_ALPHA32F_ARB) {
2280      printf("Convert luminance float tex to int %d x %d\n", width, height);
2281      return GL_LUMINANCE_ALPHA;
2282   }
2283   else if (internalFormat == GL_LUMINANCE16F_ARB ||
2284            internalFormat == GL_LUMINANCE32F_ARB) {
2285      printf("Convert luminance float tex to int %d x %d\n", width, height);
2286      return GL_LUMINANCE;
2287   }
2288   else if (internalFormat == GL_ALPHA16F_ARB ||
2289            internalFormat == GL_ALPHA32F_ARB) {
2290      printf("Convert luminance float tex to int %d x %d\n", width, height);
2291      return GL_ALPHA;
2292   }
2293   /*
2294   else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
2295      internalFormat = GL_RGBA;
2296   }
2297   */
2298   else {
2299      return internalFormat;
2300   }
2301#else
2302   return internalFormat;
2303#endif
2304}
2305
2306
2307/**
2308 * Choose the actual hardware format for a texture image.
2309 * Try to use the same format as the previous image level when possible.
2310 * Otherwise, ask the driver for the best format.
2311 * It's important to try to choose a consistant format for all levels
2312 * for efficient texture memory layout/allocation.  In particular, this
2313 * comes up during automatic mipmap generation.
2314 */
2315gl_format
2316_mesa_choose_texture_format(struct gl_context *ctx,
2317                            struct gl_texture_object *texObj,
2318                            GLenum target, GLint level,
2319                            GLenum internalFormat, GLenum format, GLenum type)
2320{
2321   gl_format f;
2322
2323   /* see if we've already chosen a format for the previous level */
2324   if (level > 0) {
2325      struct gl_texture_image *prevImage =
2326	 _mesa_select_tex_image(ctx, texObj, target, level - 1);
2327      /* See if the prev level is defined and has an internal format which
2328       * matches the new internal format.
2329       */
2330      if (prevImage &&
2331          prevImage->Width > 0 &&
2332          prevImage->InternalFormat == internalFormat) {
2333         /* use the same format */
2334         ASSERT(prevImage->TexFormat != MESA_FORMAT_NONE);
2335         return prevImage->TexFormat;
2336      }
2337   }
2338
2339   /* choose format from scratch */
2340   f = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
2341   ASSERT(f != MESA_FORMAT_NONE);
2342   return f;
2343}
2344
2345
2346/**
2347 * Common code to implement all the glTexImage1D/2D/3D functions.
2348 */
2349static void
2350teximage(struct gl_context *ctx, GLuint dims,
2351         GLenum target, GLint level, GLint internalFormat,
2352         GLsizei width, GLsizei height, GLsizei depth,
2353         GLint border, GLenum format, GLenum type,
2354         const GLvoid *pixels)
2355{
2356   GLboolean error;
2357
2358   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2359
2360   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2361      _mesa_debug(ctx, "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
2362                  dims,
2363                  _mesa_lookup_enum_by_nr(target), level,
2364                  _mesa_lookup_enum_by_nr(internalFormat),
2365                  width, height, depth, border,
2366                  _mesa_lookup_enum_by_nr(format),
2367                  _mesa_lookup_enum_by_nr(type), pixels);
2368
2369   internalFormat = override_internal_format(internalFormat, width, height);
2370
2371   /* target error checking */
2372   if (!legal_teximage_target(ctx, dims, target)) {
2373      _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage%uD(target=%s)",
2374                  dims, _mesa_lookup_enum_by_nr(target));
2375      return;
2376   }
2377
2378   /* general error checking */
2379   error = texture_error_check(ctx, dims, target, level, internalFormat,
2380                               format, type, width, height, depth, border);
2381
2382   if (_mesa_is_proxy_texture(target)) {
2383      /* Proxy texture: just clear or set state depending on error checking */
2384      struct gl_texture_image *texImage =
2385         _mesa_get_proxy_tex_image(ctx, target, level);
2386
2387      if (error) {
2388         /* when error, clear all proxy texture image parameters */
2389         if (texImage)
2390            clear_teximage_fields(texImage);
2391      }
2392      else {
2393         /* no error, set the tex image parameters */
2394         struct gl_texture_object *texObj =
2395            _mesa_get_current_tex_object(ctx, target);
2396         gl_format texFormat = _mesa_choose_texture_format(ctx, texObj,
2397                                                           target, level,
2398                                                           internalFormat,
2399                                                           format, type);
2400
2401         if (legal_texture_size(ctx, texFormat, width, height, depth)) {
2402            _mesa_init_teximage_fields(ctx, target, texImage, width, height,
2403                                       depth, border, internalFormat,
2404                                       texFormat);
2405         }
2406         else if (texImage) {
2407            clear_teximage_fields(texImage);
2408         }
2409      }
2410   }
2411   else {
2412      /* non-proxy target */
2413      const GLuint face = _mesa_tex_target_to_face(target);
2414      struct gl_texture_object *texObj;
2415      struct gl_texture_image *texImage;
2416
2417      if (error) {
2418         return;   /* error was recorded */
2419      }
2420
2421      if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
2422	 _mesa_update_state(ctx);
2423
2424      texObj = _mesa_get_current_tex_object(ctx, target);
2425
2426      _mesa_lock_texture(ctx, texObj);
2427      {
2428	 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
2429
2430	 if (!texImage) {
2431	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
2432	 }
2433         else {
2434            gl_format texFormat;
2435
2436            if (texImage->Data) {
2437               ctx->Driver.FreeTexImageData( ctx, texImage );
2438            }
2439
2440            ASSERT(texImage->Data == NULL);
2441            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
2442                                                    internalFormat, format,
2443                                                    type);
2444
2445            if (legal_texture_size(ctx, texFormat, width, height, depth)) {
2446               _mesa_init_teximage_fields(ctx, target, texImage,
2447                                          width, height, depth,
2448                                          border, internalFormat, texFormat);
2449
2450               /* Give the texture to the driver.  <pixels> may be null. */
2451               ASSERT(ctx->Driver.TexImage3D);
2452               switch (dims) {
2453               case 1:
2454                  ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
2455                                         width, border, format,
2456                                         type, pixels, &ctx->Unpack, texObj,
2457                                         texImage);
2458                  break;
2459               case 2:
2460                  ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
2461                                         width, height, border, format,
2462                                         type, pixels, &ctx->Unpack, texObj,
2463                                         texImage);
2464                  break;
2465               case 3:
2466                  ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
2467                                         width, height, depth, border, format,
2468                                         type, pixels, &ctx->Unpack, texObj,
2469                                         texImage);
2470                  break;
2471               default:
2472                  _mesa_problem(ctx, "invalid dims=%u in teximage()", dims);
2473               }
2474
2475               check_gen_mipmap(ctx, target, texObj, level);
2476
2477               update_fbo_texture(ctx, texObj, face, level);
2478
2479               /* state update */
2480               texObj->_Complete = GL_FALSE;
2481               ctx->NewState |= _NEW_TEXTURE;
2482            }
2483            else {
2484               _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
2485            }
2486         }
2487      }
2488      _mesa_unlock_texture(ctx, texObj);
2489   }
2490}
2491
2492
2493/*
2494 * Called from the API.  Note that width includes the border.
2495 */
2496void GLAPIENTRY
2497_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
2498                  GLsizei width, GLint border, GLenum format,
2499                  GLenum type, const GLvoid *pixels )
2500{
2501   GET_CURRENT_CONTEXT(ctx);
2502   teximage(ctx, 1, target, level, internalFormat, width, 1, 1,
2503            border, format, type, pixels);
2504}
2505
2506
2507void GLAPIENTRY
2508_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
2509                  GLsizei width, GLsizei height, GLint border,
2510                  GLenum format, GLenum type,
2511                  const GLvoid *pixels )
2512{
2513   GET_CURRENT_CONTEXT(ctx);
2514   teximage(ctx, 2, target, level, internalFormat, width, height, 1,
2515            border, format, type, pixels);
2516}
2517
2518
2519/*
2520 * Called by the API or display list executor.
2521 * Note that width and height include the border.
2522 */
2523void GLAPIENTRY
2524_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
2525                  GLsizei width, GLsizei height, GLsizei depth,
2526                  GLint border, GLenum format, GLenum type,
2527                  const GLvoid *pixels )
2528{
2529   GET_CURRENT_CONTEXT(ctx);
2530   teximage(ctx, 3, target, level, internalFormat, width, height, depth,
2531            border, format, type, pixels);
2532}
2533
2534
2535void GLAPIENTRY
2536_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat,
2537                     GLsizei width, GLsizei height, GLsizei depth,
2538                     GLint border, GLenum format, GLenum type,
2539                     const GLvoid *pixels )
2540{
2541   _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height,
2542                    depth, border, format, type, pixels);
2543}
2544
2545
2546#if FEATURE_OES_EGL_image
2547void GLAPIENTRY
2548_mesa_EGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image)
2549{
2550   struct gl_texture_object *texObj;
2551   struct gl_texture_image *texImage;
2552   GET_CURRENT_CONTEXT(ctx);
2553   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2554
2555   if (!ctx->Extensions.OES_EGL_image) {
2556      _mesa_error(ctx, GL_INVALID_OPERATION,
2557                  "glEGLImageTargetTexture2DOES(unsupported)");
2558      return;
2559   }
2560
2561   if (target != GL_TEXTURE_2D) {
2562      _mesa_error(ctx, GL_INVALID_ENUM,
2563		  "glEGLImageTargetTexture2D(target=%d)", target);
2564      return;
2565   }
2566
2567   if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
2568      _mesa_update_state(ctx);
2569
2570   texObj = _mesa_get_current_tex_object(ctx, target);
2571   _mesa_lock_texture(ctx, texObj);
2572
2573   texImage = _mesa_get_tex_image(ctx, texObj, target, 0);
2574   if (!texImage) {
2575      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEGLImageTargetTexture2D");
2576   } else {
2577      if (texImage->Data)
2578	 ctx->Driver.FreeTexImageData( ctx, texImage );
2579
2580      ASSERT(texImage->Data == NULL);
2581      ctx->Driver.EGLImageTargetTexture2D(ctx, target,
2582					  texObj, texImage, image);
2583
2584      /* state update */
2585      texObj->_Complete = GL_FALSE;
2586      ctx->NewState |= _NEW_TEXTURE;
2587   }
2588   _mesa_unlock_texture(ctx, texObj);
2589
2590}
2591#endif
2592
2593
2594
2595/**
2596 * Implement all the glTexSubImage1/2/3D() functions.
2597 */
2598static void
2599texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
2600            GLint xoffset, GLint yoffset, GLint zoffset,
2601            GLsizei width, GLsizei height, GLsizei depth,
2602            GLenum format, GLenum type, const GLvoid *pixels )
2603{
2604   struct gl_texture_object *texObj;
2605   struct gl_texture_image *texImage;
2606
2607   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2608
2609   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2610      _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
2611                  dims,
2612                  _mesa_lookup_enum_by_nr(target), level,
2613                  xoffset, yoffset, zoffset, width, height, depth,
2614                  _mesa_lookup_enum_by_nr(format),
2615                  _mesa_lookup_enum_by_nr(type), pixels);
2616
2617   /* check target (proxies not allowed) */
2618   if (!legal_teximage_target(ctx, dims, target) ||
2619       _mesa_is_proxy_texture(target)) {
2620      _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
2621                  dims, _mesa_lookup_enum_by_nr(target));
2622      return;
2623   }
2624
2625   if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
2626      _mesa_update_state(ctx);
2627
2628   if (subtexture_error_check(ctx, dims, target, level, xoffset, yoffset, zoffset,
2629                              width, height, depth, format, type)) {
2630      return;   /* error was detected */
2631   }
2632
2633   texObj = _mesa_get_current_tex_object(ctx, target);
2634
2635   _mesa_lock_texture(ctx, texObj);
2636   {
2637      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
2638
2639      if (subtexture_error_check2(ctx, dims, target, level,
2640                                  xoffset, yoffset, zoffset,
2641				  width, height, depth,
2642                                  format, type, texImage)) {
2643         /* error was recorded */
2644      }
2645      else if (width > 0 && height > 0 && height > 0) {
2646         /* If we have a border, offset=-1 is legal.  Bias by border width. */
2647         switch (dims) {
2648         case 3:
2649            zoffset += texImage->Border;
2650            /* fall-through */
2651         case 2:
2652            yoffset += texImage->Border;
2653            /* fall-through */
2654         case 1:
2655            xoffset += texImage->Border;
2656         }
2657
2658         switch (dims) {
2659         case 1:
2660            ctx->Driver.TexSubImage1D(ctx, target, level,
2661                                      xoffset, width,
2662                                      format, type, pixels,
2663                                      &ctx->Unpack, texObj, texImage );
2664            break;
2665         case 2:
2666            ctx->Driver.TexSubImage2D(ctx, target, level,
2667                                      xoffset, yoffset, width, height,
2668                                      format, type, pixels,
2669                                      &ctx->Unpack, texObj, texImage );
2670            break;
2671         case 3:
2672            ctx->Driver.TexSubImage3D(ctx, target, level,
2673                                      xoffset, yoffset, zoffset,
2674                                      width, height, depth,
2675                                      format, type, pixels,
2676                                      &ctx->Unpack, texObj, texImage );
2677            break;
2678         default:
2679            _mesa_problem(ctx, "unexpected dims in subteximage()");
2680         }
2681
2682         check_gen_mipmap(ctx, target, texObj, level);
2683
2684         ctx->NewState |= _NEW_TEXTURE;
2685      }
2686   }
2687   _mesa_unlock_texture(ctx, texObj);
2688}
2689
2690
2691void GLAPIENTRY
2692_mesa_TexSubImage1D( GLenum target, GLint level,
2693                     GLint xoffset, GLsizei width,
2694                     GLenum format, GLenum type,
2695                     const GLvoid *pixels )
2696{
2697   GET_CURRENT_CONTEXT(ctx);
2698   texsubimage(ctx, 1, target, level,
2699               xoffset, 0, 0,
2700               width, 1, 1,
2701               format, type, pixels);
2702}
2703
2704
2705void GLAPIENTRY
2706_mesa_TexSubImage2D( GLenum target, GLint level,
2707                     GLint xoffset, GLint yoffset,
2708                     GLsizei width, GLsizei height,
2709                     GLenum format, GLenum type,
2710                     const GLvoid *pixels )
2711{
2712   GET_CURRENT_CONTEXT(ctx);
2713   texsubimage(ctx, 2, target, level,
2714               xoffset, yoffset, 0,
2715               width, height, 1,
2716               format, type, pixels);
2717}
2718
2719
2720
2721void GLAPIENTRY
2722_mesa_TexSubImage3D( GLenum target, GLint level,
2723                     GLint xoffset, GLint yoffset, GLint zoffset,
2724                     GLsizei width, GLsizei height, GLsizei depth,
2725                     GLenum format, GLenum type,
2726                     const GLvoid *pixels )
2727{
2728   GET_CURRENT_CONTEXT(ctx);
2729   texsubimage(ctx, 3, target, level,
2730               xoffset, yoffset, zoffset,
2731               width, height, depth,
2732               format, type, pixels);
2733}
2734
2735
2736
2737/**
2738 * Implement the glCopyTexImage1/2D() functions.
2739 */
2740static void
2741copyteximage(struct gl_context *ctx, GLuint dims,
2742             GLenum target, GLint level, GLenum internalFormat,
2743             GLint x, GLint y, GLsizei width, GLsizei height, GLint border )
2744{
2745   struct gl_texture_object *texObj;
2746   struct gl_texture_image *texImage;
2747   const GLuint face = _mesa_tex_target_to_face(target);
2748
2749   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2750
2751   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2752      _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
2753                  dims,
2754                  _mesa_lookup_enum_by_nr(target), level,
2755                  _mesa_lookup_enum_by_nr(internalFormat),
2756                  x, y, width, height, border);
2757
2758   if (ctx->NewState & NEW_COPY_TEX_STATE)
2759      _mesa_update_state(ctx);
2760
2761   if (copytexture_error_check(ctx, dims, target, level, internalFormat,
2762                               width, height, border))
2763      return;
2764
2765   texObj = _mesa_get_current_tex_object(ctx, target);
2766
2767   _mesa_lock_texture(ctx, texObj);
2768   {
2769      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
2770
2771      if (!texImage) {
2772	 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
2773      }
2774      else {
2775         gl_format texFormat;
2776
2777         if (texImage->Data) {
2778            ctx->Driver.FreeTexImageData( ctx, texImage );
2779         }
2780
2781         ASSERT(texImage->Data == NULL);
2782
2783         texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
2784                                                 internalFormat, GL_NONE,
2785                                                 GL_NONE);
2786
2787         if (legal_texture_size(ctx, texFormat, width, height, 1)) {
2788            _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
2789                                       border, internalFormat, texFormat);
2790
2791            ASSERT(ctx->Driver.CopyTexImage2D);
2792            if (dims == 1)
2793               ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
2794                                          x, y, width, border);
2795            else
2796               ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
2797                                          x, y, width, height, border);
2798
2799            check_gen_mipmap(ctx, target, texObj, level);
2800
2801            update_fbo_texture(ctx, texObj, face, level);
2802
2803            /* state update */
2804            texObj->_Complete = GL_FALSE;
2805            ctx->NewState |= _NEW_TEXTURE;
2806         }
2807         else {
2808            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
2809         }
2810      }
2811   }
2812   _mesa_unlock_texture(ctx, texObj);
2813}
2814
2815
2816
2817void GLAPIENTRY
2818_mesa_CopyTexImage1D( GLenum target, GLint level,
2819                      GLenum internalFormat,
2820                      GLint x, GLint y,
2821                      GLsizei width, GLint border )
2822{
2823   GET_CURRENT_CONTEXT(ctx);
2824   copyteximage(ctx, 1, target, level, internalFormat, x, y, width, 1, border);
2825}
2826
2827
2828
2829void GLAPIENTRY
2830_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
2831                      GLint x, GLint y, GLsizei width, GLsizei height,
2832                      GLint border )
2833{
2834   GET_CURRENT_CONTEXT(ctx);
2835   copyteximage(ctx, 2, target, level, internalFormat,
2836                x, y, width, height, border);
2837}
2838
2839
2840
2841/**
2842 * Implementation for glCopyTexSubImage1/2/3D() functions.
2843 */
2844static void
2845copytexsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
2846                GLint xoffset, GLint yoffset, GLint zoffset,
2847                GLint x, GLint y, GLsizei width, GLsizei height)
2848{
2849   struct gl_texture_object *texObj;
2850   struct gl_texture_image *texImage;
2851
2852   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
2853
2854   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
2855      _mesa_debug(ctx, "glCopyTexSubImage%uD %s %d %d %d %d %d %d %d %d\n",
2856                  dims,
2857                  _mesa_lookup_enum_by_nr(target),
2858                  level, xoffset, yoffset, zoffset, x, y, width, height);
2859
2860   if (ctx->NewState & NEW_COPY_TEX_STATE)
2861      _mesa_update_state(ctx);
2862
2863   if (copytexsubimage_error_check1(ctx, dims, target, level))
2864      return;
2865
2866   texObj = _mesa_get_current_tex_object(ctx, target);
2867
2868   _mesa_lock_texture(ctx, texObj);
2869   {
2870      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
2871
2872      if (copytexsubimage_error_check2(ctx, dims, target, level, xoffset, yoffset,
2873				       zoffset, width, height, texImage)) {
2874         /* error was recored */
2875      }
2876      else {
2877         /* If we have a border, offset=-1 is legal.  Bias by border width. */
2878         switch (dims) {
2879         case 3:
2880            zoffset += texImage->Border;
2881            /* fall-through */
2882         case 2:
2883            yoffset += texImage->Border;
2884            /* fall-through */
2885         case 1:
2886            xoffset += texImage->Border;
2887         }
2888
2889         if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
2890                                        &width, &height)) {
2891            switch (dims) {
2892            case 1:
2893               ctx->Driver.CopyTexSubImage1D(ctx, target, level,
2894                                             xoffset, x, y, width);
2895               break;
2896            case 2:
2897               ctx->Driver.CopyTexSubImage2D(ctx, target, level,
2898                                             xoffset, yoffset,
2899                                             x, y, width, height);
2900               break;
2901            case 3:
2902               ctx->Driver.CopyTexSubImage3D(ctx, target, level,
2903                                             xoffset, yoffset, zoffset,
2904                                             x, y, width, height);
2905               break;
2906            default:
2907               _mesa_problem(ctx, "bad dims in copytexsubimage()");
2908            }
2909
2910            check_gen_mipmap(ctx, target, texObj, level);
2911
2912            ctx->NewState |= _NEW_TEXTURE;
2913         }
2914      }
2915   }
2916   _mesa_unlock_texture(ctx, texObj);
2917}
2918
2919
2920void GLAPIENTRY
2921_mesa_CopyTexSubImage1D( GLenum target, GLint level,
2922                         GLint xoffset, GLint x, GLint y, GLsizei width )
2923{
2924   GET_CURRENT_CONTEXT(ctx);
2925   copytexsubimage(ctx, 1, target, level, xoffset, 0, 0, x, y, width, 1);
2926}
2927
2928
2929
2930void GLAPIENTRY
2931_mesa_CopyTexSubImage2D( GLenum target, GLint level,
2932                         GLint xoffset, GLint yoffset,
2933                         GLint x, GLint y, GLsizei width, GLsizei height )
2934{
2935   GET_CURRENT_CONTEXT(ctx);
2936   copytexsubimage(ctx, 2, target, level, xoffset, yoffset, 0, x, y,
2937                   width, height);
2938}
2939
2940
2941
2942void GLAPIENTRY
2943_mesa_CopyTexSubImage3D( GLenum target, GLint level,
2944                         GLint xoffset, GLint yoffset, GLint zoffset,
2945                         GLint x, GLint y, GLsizei width, GLsizei height )
2946{
2947   GET_CURRENT_CONTEXT(ctx);
2948   copytexsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset,
2949                   x, y, width, height);
2950}
2951
2952
2953
2954
2955/**********************************************************************/
2956/******                   Compressed Textures                    ******/
2957/**********************************************************************/
2958
2959
2960/**
2961 * Return expected size of a compressed texture.
2962 */
2963static GLuint
2964compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
2965                    GLenum glformat)
2966{
2967   gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
2968   return _mesa_format_image_size(mesaFormat, width, height, depth);
2969}
2970
2971
2972/*
2973 * Return compressed texture block size, in pixels.
2974 */
2975static void
2976get_compressed_block_size(GLenum glformat, GLuint *bw, GLuint *bh)
2977{
2978   gl_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
2979   _mesa_get_format_block_size(mesaFormat, bw, bh);
2980}
2981
2982
2983/**
2984 * Error checking for glCompressedTexImage[123]D().
2985 * \return error code or GL_NO_ERROR.
2986 */
2987static GLenum
2988compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
2989                               GLenum target, GLint level,
2990                               GLenum internalFormat, GLsizei width,
2991                               GLsizei height, GLsizei depth, GLint border,
2992                               GLsizei imageSize)
2993{
2994   const GLenum proxyTarget = get_proxy_target(target);
2995   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
2996   GLint expectedSize;
2997
2998   /* check level */
2999   if (level < 0 || level >= maxLevels)
3000      return GL_INVALID_VALUE;
3001
3002   /* This will detect any invalid internalFormat value */
3003   if (!_mesa_is_compressed_format(ctx, internalFormat))
3004      return GL_INVALID_ENUM;
3005
3006   /* This should really never fail */
3007   if (_mesa_base_tex_format(ctx, internalFormat) < 0)
3008      return GL_INVALID_ENUM;
3009
3010   /* No compressed formats support borders at this time */
3011   if (border != 0)
3012      return GL_INVALID_VALUE;
3013
3014   /* For cube map, width must equal height */
3015   if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
3016       target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB && width != height)
3017      return GL_INVALID_VALUE;
3018
3019   /* check image sizes */
3020   if (!ctx->Driver.TestProxyTexImage(ctx, proxyTarget, level,
3021                                      internalFormat, GL_NONE, GL_NONE,
3022                                      width, height, depth, border)) {
3023      return GL_INVALID_VALUE;
3024   }
3025
3026   /* check image size in bytes */
3027   expectedSize = compressed_tex_size(width, height, depth, internalFormat);
3028   if (expectedSize != imageSize)
3029      return GL_INVALID_VALUE;
3030
3031   return GL_NO_ERROR;
3032}
3033
3034
3035/**
3036 * Error checking for glCompressedTexSubImage[123]D().
3037 * \warning  There are some bad assumptions here about the size of compressed
3038 *           texture tiles (multiple of 4) used to test the validity of the
3039 *           offset and size parameters.
3040 * \return error code or GL_NO_ERROR.
3041 */
3042static GLenum
3043compressed_subtexture_error_check(struct gl_context *ctx, GLint dimensions,
3044                                  GLenum target, GLint level,
3045                                  GLint xoffset, GLint yoffset, GLint zoffset,
3046                                  GLsizei width, GLsizei height, GLsizei depth,
3047                                  GLenum format, GLsizei imageSize)
3048{
3049   GLint expectedSize, maxLevels = 0, maxTextureSize;
3050   GLuint bw, bh;
3051   (void) zoffset;
3052
3053   if (dimensions == 1) {
3054      /* 1D compressed textures not allowed */
3055      return GL_INVALID_ENUM;
3056   }
3057   else if (dimensions == 2) {
3058      if (target == GL_PROXY_TEXTURE_2D) {
3059         maxLevels = ctx->Const.MaxTextureLevels;
3060      }
3061      else if (target == GL_TEXTURE_2D) {
3062         maxLevels = ctx->Const.MaxTextureLevels;
3063      }
3064      else if (target == GL_PROXY_TEXTURE_CUBE_MAP_ARB) {
3065         if (!ctx->Extensions.ARB_texture_cube_map)
3066            return GL_INVALID_ENUM; /*target*/
3067         maxLevels = ctx->Const.MaxCubeTextureLevels;
3068      }
3069      else if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
3070               target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) {
3071         if (!ctx->Extensions.ARB_texture_cube_map)
3072            return GL_INVALID_ENUM; /*target*/
3073         maxLevels = ctx->Const.MaxCubeTextureLevels;
3074      }
3075      else {
3076         return GL_INVALID_ENUM; /*target*/
3077      }
3078   }
3079   else if (dimensions == 3) {
3080      /* 3D compressed textures not allowed */
3081      return GL_INVALID_ENUM;
3082   }
3083
3084   maxTextureSize = 1 << (maxLevels - 1);
3085
3086   /* this will catch any invalid compressed format token */
3087   if (!_mesa_is_compressed_format(ctx, format))
3088      return GL_INVALID_ENUM;
3089
3090   if (width < 1 || width > maxTextureSize)
3091      return GL_INVALID_VALUE;
3092
3093   if ((height < 1 || height > maxTextureSize)
3094       && dimensions > 1)
3095      return GL_INVALID_VALUE;
3096
3097   if (level < 0 || level >= maxLevels)
3098      return GL_INVALID_VALUE;
3099
3100   /*
3101    * do checks which depend on compression block size
3102    */
3103   get_compressed_block_size(format, &bw, &bh);
3104
3105   if ((xoffset % bw != 0) || (yoffset % bh != 0))
3106      return GL_INVALID_VALUE;
3107
3108   if ((width % bw != 0) && width != 2 && width != 1)
3109      return GL_INVALID_VALUE;
3110
3111   if ((height % bh != 0) && height != 2 && height != 1)
3112      return GL_INVALID_VALUE;
3113
3114   expectedSize = compressed_tex_size(width, height, depth, format);
3115   if (expectedSize != imageSize)
3116      return GL_INVALID_VALUE;
3117
3118   return GL_NO_ERROR;
3119}
3120
3121
3122/**
3123 * Do second part of glCompressedTexSubImage error checking.
3124 * \return GL_TRUE if error found, GL_FALSE otherwise.
3125 */
3126static GLboolean
3127compressed_subtexture_error_check2(struct gl_context *ctx, GLuint dims,
3128                                   GLsizei width, GLsizei height,
3129                                   GLsizei depth, GLenum format,
3130                                   struct gl_texture_image *texImage)
3131{
3132
3133   if ((GLint) format != texImage->InternalFormat) {
3134      _mesa_error(ctx, GL_INVALID_OPERATION,
3135                  "glCompressedTexSubImage%uD(format=0x%x)", dims, format);
3136      return GL_TRUE;
3137   }
3138
3139   if (((width == 1 || width == 2) &&
3140        width != (GLsizei) texImage->Width) ||
3141       (width > (GLsizei) texImage->Width)) {
3142      _mesa_error(ctx, GL_INVALID_VALUE,
3143                  "glCompressedTexSubImage%uD(width=%d)", dims, width);
3144      return GL_TRUE;
3145   }
3146
3147   if (dims >= 2) {
3148      if (((height == 1 || height == 2) &&
3149           height != (GLsizei) texImage->Height) ||
3150          (height > (GLsizei) texImage->Height)) {
3151         _mesa_error(ctx, GL_INVALID_VALUE,
3152                     "glCompressedTexSubImage%uD(height=%d)", dims, height);
3153         return GL_TRUE;
3154      }
3155   }
3156
3157   if (dims >= 3) {
3158      if (((depth == 1 || depth == 2) &&
3159           depth != (GLsizei) texImage->Depth) ||
3160          (depth > (GLsizei) texImage->Depth)) {
3161         _mesa_error(ctx, GL_INVALID_VALUE,
3162                     "glCompressedTexSubImage%uD(depth=%d)", dims, depth);
3163         return GL_TRUE;
3164      }
3165   }
3166
3167   return GL_FALSE;
3168}
3169
3170
3171/**
3172 * Implementation of the glCompressedTexImage1/2/3D() functions.
3173 */
3174static void
3175compressedteximage(struct gl_context *ctx, GLuint dims,
3176                   GLenum target, GLint level,
3177                   GLenum internalFormat, GLsizei width,
3178                   GLsizei height, GLsizei depth, GLint border,
3179                   GLsizei imageSize, const GLvoid *data)
3180{
3181   GLenum error;
3182
3183   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3184
3185   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3186      _mesa_debug(ctx,
3187                  "glCompressedTexImage%uDARB %s %d %s %d %d %d %d %d %p\n",
3188                  dims,
3189                  _mesa_lookup_enum_by_nr(target), level,
3190                  _mesa_lookup_enum_by_nr(internalFormat),
3191                  width, height, depth, border, imageSize, data);
3192
3193   /* check target */
3194   if (!legal_compressed_teximage_target(ctx, dims, target)) {
3195      _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target=%s)",
3196                  dims, _mesa_lookup_enum_by_nr(target));
3197      return;
3198   }
3199
3200   error = compressed_texture_error_check(ctx, dims, target, level,
3201                                          internalFormat, width, height, depth,
3202                                          border, imageSize);
3203
3204#if FEATURE_ES
3205   /* XXX this is kind of a hack */
3206   if (error) {
3207      _mesa_error(ctx, error, "glTexImage2D");
3208      return;
3209   }
3210
3211   if (dims == 2) {
3212      switch (internalFormat) {
3213      case GL_PALETTE4_RGB8_OES:
3214      case GL_PALETTE4_RGBA8_OES:
3215      case GL_PALETTE4_R5_G6_B5_OES:
3216      case GL_PALETTE4_RGBA4_OES:
3217      case GL_PALETTE4_RGB5_A1_OES:
3218      case GL_PALETTE8_RGB8_OES:
3219      case GL_PALETTE8_RGBA8_OES:
3220      case GL_PALETTE8_R5_G6_B5_OES:
3221      case GL_PALETTE8_RGBA4_OES:
3222      case GL_PALETTE8_RGB5_A1_OES:
3223         _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
3224                                          width, height, imageSize, data);
3225         return;
3226      }
3227   }
3228#endif
3229
3230   if (_mesa_is_proxy_texture(target)) {
3231      /* Proxy texture: just check for errors and update proxy state */
3232      struct gl_texture_image *texImage;
3233
3234      if (!error) {
3235         struct gl_texture_object *texObj =
3236            _mesa_get_current_tex_object(ctx, target);
3237         gl_format texFormat =
3238            _mesa_choose_texture_format(ctx, texObj, target, level,
3239                                        internalFormat, GL_NONE, GL_NONE);
3240         if (!legal_texture_size(ctx, texFormat, width, height, depth)) {
3241            error = GL_OUT_OF_MEMORY;
3242         }
3243      }
3244
3245      texImage = _mesa_get_proxy_tex_image(ctx, target, level);
3246      if (texImage) {
3247         if (error) {
3248            /* if error, clear all proxy texture image parameters */
3249            clear_teximage_fields(texImage);
3250         }
3251         else {
3252            /* no error: store the teximage parameters */
3253            _mesa_init_teximage_fields(ctx, target, texImage, width, height,
3254                                       depth, border, internalFormat,
3255                                       MESA_FORMAT_NONE);
3256         }
3257      }
3258   }
3259   else {
3260      /* non-proxy target */
3261      struct gl_texture_object *texObj;
3262      struct gl_texture_image *texImage;
3263
3264      if (error) {
3265         _mesa_error(ctx, error, "glCompressedTexImage%uD", dims);
3266         return;
3267      }
3268
3269      texObj = _mesa_get_current_tex_object(ctx, target);
3270
3271      _mesa_lock_texture(ctx, texObj);
3272      {
3273	 texImage = _mesa_get_tex_image(ctx, texObj, target, level);
3274	 if (!texImage) {
3275	    _mesa_error(ctx, GL_OUT_OF_MEMORY,
3276                        "glCompressedTexImage%uD", dims);
3277	 }
3278         else {
3279            gl_format texFormat;
3280
3281            if (texImage->Data) {
3282               ctx->Driver.FreeTexImageData( ctx, texImage );
3283            }
3284            ASSERT(texImage->Data == NULL);
3285
3286            texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
3287                                                    internalFormat, GL_NONE,
3288                                                    GL_NONE);
3289
3290            if (legal_texture_size(ctx, texFormat, width, height, depth)) {
3291               _mesa_init_teximage_fields(ctx, target, texImage,
3292                                          width, height, depth,
3293                                          border, internalFormat, texFormat);
3294
3295               switch (dims) {
3296               case 1:
3297                  ASSERT(ctx->Driver.CompressedTexImage1D);
3298                  ctx->Driver.CompressedTexImage1D(ctx, target, level,
3299                                                   internalFormat,
3300                                                   width,
3301                                                   border, imageSize, data,
3302                                                   texObj, texImage);
3303                  break;
3304               case 2:
3305                  ASSERT(ctx->Driver.CompressedTexImage2D);
3306                  ctx->Driver.CompressedTexImage2D(ctx, target, level,
3307                                                   internalFormat,
3308                                                   width, height,
3309                                                   border, imageSize, data,
3310                                                   texObj, texImage);
3311                  break;
3312               case 3:
3313                  ASSERT(ctx->Driver.CompressedTexImage3D);
3314                  ctx->Driver.CompressedTexImage3D(ctx, target, level,
3315                                                   internalFormat,
3316                                                   width, height, depth,
3317                                                   border, imageSize, data,
3318                                                   texObj, texImage);
3319                  break;
3320               default:
3321                  _mesa_problem(ctx, "bad dims in compressedteximage");
3322               }
3323
3324               check_gen_mipmap(ctx, target, texObj, level);
3325
3326               /* state update */
3327               texObj->_Complete = GL_FALSE;
3328               ctx->NewState |= _NEW_TEXTURE;
3329            }
3330            else {
3331               _mesa_error(ctx, GL_OUT_OF_MEMORY,
3332                           "glCompressedTexImage%uD", dims);
3333            }
3334         }
3335      }
3336      _mesa_unlock_texture(ctx, texObj);
3337   }
3338}
3339
3340
3341void GLAPIENTRY
3342_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
3343                              GLenum internalFormat, GLsizei width,
3344                              GLint border, GLsizei imageSize,
3345                              const GLvoid *data)
3346{
3347   GET_CURRENT_CONTEXT(ctx);
3348   compressedteximage(ctx, 1, target, level, internalFormat,
3349                      width, 1, 1, border, imageSize, data);
3350}
3351
3352
3353void GLAPIENTRY
3354_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
3355                              GLenum internalFormat, GLsizei width,
3356                              GLsizei height, GLint border, GLsizei imageSize,
3357                              const GLvoid *data)
3358{
3359   GET_CURRENT_CONTEXT(ctx);
3360   compressedteximage(ctx, 2, target, level, internalFormat,
3361                      width, height, 1, border, imageSize, data);
3362}
3363
3364
3365void GLAPIENTRY
3366_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
3367                              GLenum internalFormat, GLsizei width,
3368                              GLsizei height, GLsizei depth, GLint border,
3369                              GLsizei imageSize, const GLvoid *data)
3370{
3371   GET_CURRENT_CONTEXT(ctx);
3372   compressedteximage(ctx, 3, target, level, internalFormat,
3373                      width, height, depth, border, imageSize, data);
3374}
3375
3376
3377/**
3378 * Common helper for glCompressedTexSubImage1/2/3D().
3379 */
3380static void
3381compressed_tex_sub_image(GLuint dims, GLenum target, GLint level,
3382                         GLint xoffset, GLint yoffset, GLint zoffset,
3383                         GLsizei width, GLsizei height, GLsizei depth,
3384                         GLenum format, GLsizei imageSize, const GLvoid *data)
3385{
3386   struct gl_texture_object *texObj;
3387   struct gl_texture_image *texImage;
3388   GLenum error;
3389   GET_CURRENT_CONTEXT(ctx);
3390   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
3391
3392   error = compressed_subtexture_error_check(ctx, dims, target, level,
3393                                             xoffset, 0, 0, /* pos */
3394                                             width, height, depth,   /* size */
3395                                             format, imageSize);
3396   if (error) {
3397      _mesa_error(ctx, error, "glCompressedTexSubImage%uD", dims);
3398      return;
3399   }
3400
3401   texObj = _mesa_get_current_tex_object(ctx, target);
3402
3403   _mesa_lock_texture(ctx, texObj);
3404   {
3405      texImage = _mesa_select_tex_image(ctx, texObj, target, level);
3406      assert(texImage);
3407
3408      if (compressed_subtexture_error_check2(ctx, dims, width, height, depth,
3409                                             format, texImage)) {
3410         /* error was recorded */
3411      }
3412      else if (width > 0 && height > 0 && depth > 0) {
3413         switch (dims) {
3414         case 1:
3415            if (ctx->Driver.CompressedTexSubImage1D) {
3416               ctx->Driver.CompressedTexSubImage1D(ctx, target, level,
3417                                                   xoffset, width,
3418                                                   format, imageSize, data,
3419                                                   texObj, texImage);
3420            }
3421            break;
3422         case 2:
3423            if (ctx->Driver.CompressedTexSubImage2D) {
3424               ctx->Driver.CompressedTexSubImage2D(ctx, target, level,
3425                                                   xoffset, yoffset,
3426                                                   width, height,
3427                                                   format, imageSize, data,
3428                                                   texObj, texImage);
3429            }
3430            break;
3431         case 3:
3432            if (ctx->Driver.CompressedTexSubImage3D) {
3433               ctx->Driver.CompressedTexSubImage3D(ctx, target, level,
3434                                                   xoffset, yoffset, zoffset,
3435                                                   width, height, depth,
3436                                                   format, imageSize, data,
3437                                                   texObj, texImage);
3438            }
3439            break;
3440         default:
3441            ;
3442         }
3443
3444         check_gen_mipmap(ctx, target, texObj, level);
3445
3446         ctx->NewState |= _NEW_TEXTURE;
3447      }
3448   }
3449   _mesa_unlock_texture(ctx, texObj);
3450}
3451
3452
3453void GLAPIENTRY
3454_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
3455                                 GLsizei width, GLenum format,
3456                                 GLsizei imageSize, const GLvoid *data)
3457{
3458   compressed_tex_sub_image(1, target, level, xoffset, 0, 0, width, 1, 1,
3459                            format, imageSize, data);
3460}
3461
3462
3463void GLAPIENTRY
3464_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
3465                                 GLint yoffset, GLsizei width, GLsizei height,
3466                                 GLenum format, GLsizei imageSize,
3467                                 const GLvoid *data)
3468{
3469   compressed_tex_sub_image(2, target, level, xoffset, yoffset, 0,
3470                            width, height, 1, format, imageSize, data);
3471}
3472
3473
3474void GLAPIENTRY
3475_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
3476                                 GLint yoffset, GLint zoffset, GLsizei width,
3477                                 GLsizei height, GLsizei depth, GLenum format,
3478                                 GLsizei imageSize, const GLvoid *data)
3479{
3480   compressed_tex_sub_image(3, target, level, xoffset, yoffset, zoffset,
3481                            width, height, depth, format, imageSize, data);
3482}
3483