OSDN Git Service

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