OSDN Git Service

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