xref: /third_party/mesa3d/src/mesa/main/teximage.c (revision bf215546)
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 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27/**
28 * \file teximage.c
29 * Texture image-related functions.
30 */
31
32#include <stdbool.h>
33#include "glheader.h"
34#include "bufferobj.h"
35#include "context.h"
36#include "enums.h"
37#include "fbobject.h"
38#include "framebuffer.h"
39#include "hash.h"
40#include "image.h"
41
42#include "macros.h"
43#include "mipmap.h"
44#include "multisample.h"
45#include "pixel.h"
46#include "pixelstore.h"
47#include "state.h"
48#include "texcompress.h"
49#include "texcompress_cpal.h"
50#include "teximage.h"
51#include "texobj.h"
52#include "texstate.h"
53#include "texstorage.h"
54#include "textureview.h"
55#include "mtypes.h"
56#include "glformats.h"
57#include "texstore.h"
58#include "pbo.h"
59#include "api_exec_decl.h"
60
61#include "util/u_memory.h"
62
63#include "state_tracker/st_cb_texture.h"
64#include "state_tracker/st_context.h"
65#include "state_tracker/st_format.h"
66#include "state_tracker/st_gen_mipmap.h"
67#include "state_tracker/st_cb_eglimage.h"
68#include "state_tracker/st_sampler_view.h"
69
70/**
71 * Returns a corresponding internal floating point format for a given base
72 * format as specifed by OES_texture_float. In case of GL_FLOAT, the internal
73 * format needs to be a 32 bit component and in case of GL_HALF_FLOAT_OES it
74 * needs to be a 16 bit component.
75 *
76 * For example, given base format GL_RGBA, type GL_FLOAT return GL_RGBA32F_ARB.
77 */
78static GLenum
79adjust_for_oes_float_texture(const struct gl_context *ctx,
80                             GLenum format, GLenum type)
81{
82   switch (type) {
83   case GL_FLOAT:
84      if (ctx->Extensions.OES_texture_float) {
85         switch (format) {
86         case GL_RGBA:
87            return GL_RGBA32F;
88         case GL_RGB:
89            return GL_RGB32F;
90         case GL_ALPHA:
91            return GL_ALPHA32F_ARB;
92         case GL_LUMINANCE:
93            return GL_LUMINANCE32F_ARB;
94         case GL_LUMINANCE_ALPHA:
95            return GL_LUMINANCE_ALPHA32F_ARB;
96         default:
97            break;
98         }
99      }
100      break;
101
102   case GL_HALF_FLOAT_OES:
103      if (ctx->Extensions.OES_texture_half_float) {
104         switch (format) {
105         case GL_RGBA:
106            return GL_RGBA16F;
107         case GL_RGB:
108            return GL_RGB16F;
109         case GL_ALPHA:
110            return GL_ALPHA16F_ARB;
111         case GL_LUMINANCE:
112            return GL_LUMINANCE16F_ARB;
113         case GL_LUMINANCE_ALPHA:
114            return GL_LUMINANCE_ALPHA16F_ARB;
115         default:
116            break;
117         }
118      }
119      break;
120
121   default:
122      break;
123   }
124
125   return format;
126}
127
128/**
129 * Returns a corresponding base format for a given internal floating point
130 * format as specifed by OES_texture_float.
131 */
132static GLenum
133oes_float_internal_format(const struct gl_context *ctx,
134                          GLenum format, GLenum type)
135{
136   switch (type) {
137   case GL_FLOAT:
138      if (ctx->Extensions.OES_texture_float) {
139         switch (format) {
140         case GL_RGBA32F:
141            return GL_RGBA;
142         case GL_RGB32F:
143            return GL_RGB;
144         case GL_ALPHA32F_ARB:
145            return GL_ALPHA;
146         case GL_LUMINANCE32F_ARB:
147            return GL_LUMINANCE;
148         case GL_LUMINANCE_ALPHA32F_ARB:
149            return GL_LUMINANCE_ALPHA;
150         default:
151            break;
152         }
153      }
154      break;
155
156   case GL_HALF_FLOAT_OES:
157      if (ctx->Extensions.OES_texture_half_float) {
158         switch (format) {
159         case GL_RGBA16F:
160            return GL_RGBA;
161         case GL_RGB16F:
162            return GL_RGB;
163         case GL_ALPHA16F_ARB:
164            return GL_ALPHA;
165         case GL_LUMINANCE16F_ARB:
166            return GL_LUMINANCE;
167         case GL_LUMINANCE_ALPHA16F_ARB:
168            return GL_LUMINANCE_ALPHA;
169         default:
170            break;
171         }
172      }
173      break;
174   }
175   return format;
176}
177
178
179/**
180 * Install gl_texture_image in a gl_texture_object according to the target
181 * and level parameters.
182 *
183 * \param tObj texture object.
184 * \param target texture target.
185 * \param level image level.
186 * \param texImage texture image.
187 */
188static void
189set_tex_image(struct gl_texture_object *tObj,
190              GLenum target, GLint level,
191              struct gl_texture_image *texImage)
192{
193   const GLuint face = _mesa_tex_target_to_face(target);
194
195   assert(tObj);
196   assert(texImage);
197   if (target == GL_TEXTURE_RECTANGLE_NV || target == GL_TEXTURE_EXTERNAL_OES)
198      assert(level == 0);
199
200   tObj->Image[face][level] = texImage;
201
202   /* Set the 'back' pointer */
203   texImage->TexObject = tObj;
204   texImage->Level = level;
205   texImage->Face = face;
206}
207
208
209/**
210 * Free a gl_texture_image and associated data.
211 * This function is a fallback.
212 *
213 * \param texImage texture image.
214 *
215 * Free the texture image structure and the associated image data.
216 */
217void
218_mesa_delete_texture_image(struct gl_context *ctx,
219                           struct gl_texture_image *texImage)
220{
221   /* Free texImage->Data and/or any other driver-specific texture
222    * image storage.
223    */
224   st_FreeTextureImageBuffer( ctx, texImage );
225   FREE(texImage);
226}
227
228
229/**
230 * Test if a target is a proxy target.
231 *
232 * \param target texture target.
233 *
234 * \return GL_TRUE if the target is a proxy target, GL_FALSE otherwise.
235 */
236GLboolean
237_mesa_is_proxy_texture(GLenum target)
238{
239   unsigned i;
240   static const GLenum targets[] = {
241      GL_PROXY_TEXTURE_1D,
242      GL_PROXY_TEXTURE_2D,
243      GL_PROXY_TEXTURE_3D,
244      GL_PROXY_TEXTURE_CUBE_MAP,
245      GL_PROXY_TEXTURE_RECTANGLE,
246      GL_PROXY_TEXTURE_1D_ARRAY,
247      GL_PROXY_TEXTURE_2D_ARRAY,
248      GL_PROXY_TEXTURE_CUBE_MAP_ARRAY,
249      GL_PROXY_TEXTURE_2D_MULTISAMPLE,
250      GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY
251   };
252   /*
253    * NUM_TEXTURE_TARGETS should match number of terms above, except there's no
254    * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
255    */
256   STATIC_ASSERT(NUM_TEXTURE_TARGETS == ARRAY_SIZE(targets) + 2);
257
258   for (i = 0; i < ARRAY_SIZE(targets); ++i)
259      if (target == targets[i])
260         return GL_TRUE;
261   return GL_FALSE;
262}
263
264
265/**
266 * Test if a target is an array target.
267 *
268 * \param target texture target.
269 *
270 * \return true if the target is an array target, false otherwise.
271 */
272bool
273_mesa_is_array_texture(GLenum target)
274{
275   switch (target) {
276   case GL_TEXTURE_1D_ARRAY:
277   case GL_TEXTURE_2D_ARRAY:
278   case GL_TEXTURE_CUBE_MAP_ARRAY:
279   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
280      return true;
281   default:
282      return false;
283   };
284}
285
286/**
287 * Test if a target is a cube map.
288 *
289 * \param target texture target.
290 *
291 * \return true if the target is a cube map, false otherwise.
292 */
293bool
294_mesa_is_cube_map_texture(GLenum target)
295{
296   switch(target) {
297   case GL_TEXTURE_CUBE_MAP:
298   case GL_TEXTURE_CUBE_MAP_ARRAY:
299      return true;
300   default:
301      return false;
302   }
303}
304
305/**
306 * Return the proxy target which corresponds to the given texture target
307 */
308static GLenum
309proxy_target(GLenum target)
310{
311   switch (target) {
312   case GL_TEXTURE_1D:
313   case GL_PROXY_TEXTURE_1D:
314      return GL_PROXY_TEXTURE_1D;
315   case GL_TEXTURE_2D:
316   case GL_PROXY_TEXTURE_2D:
317      return GL_PROXY_TEXTURE_2D;
318   case GL_TEXTURE_3D:
319   case GL_PROXY_TEXTURE_3D:
320      return GL_PROXY_TEXTURE_3D;
321   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
322   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
323   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
324   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
325   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
326   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
327   case GL_TEXTURE_CUBE_MAP:
328   case GL_PROXY_TEXTURE_CUBE_MAP:
329      return GL_PROXY_TEXTURE_CUBE_MAP;
330   case GL_TEXTURE_RECTANGLE_NV:
331   case GL_PROXY_TEXTURE_RECTANGLE_NV:
332      return GL_PROXY_TEXTURE_RECTANGLE_NV;
333   case GL_TEXTURE_1D_ARRAY_EXT:
334   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
335      return GL_PROXY_TEXTURE_1D_ARRAY_EXT;
336   case GL_TEXTURE_2D_ARRAY_EXT:
337   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
338      return GL_PROXY_TEXTURE_2D_ARRAY_EXT;
339   case GL_TEXTURE_CUBE_MAP_ARRAY:
340   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
341      return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY;
342   case GL_TEXTURE_2D_MULTISAMPLE:
343   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
344      return GL_PROXY_TEXTURE_2D_MULTISAMPLE;
345   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
346   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
347      return GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY;
348   default:
349      _mesa_problem(NULL, "unexpected target in proxy_target()");
350      return 0;
351   }
352}
353
354
355
356
357/**
358 * Get a texture image pointer from a texture object, given a texture
359 * target and mipmap level.  The target and level parameters should
360 * have already been error-checked.
361 *
362 * \param texObj texture unit.
363 * \param target texture target.
364 * \param level image level.
365 *
366 * \return pointer to the texture image structure, or NULL on failure.
367 */
368struct gl_texture_image *
369_mesa_select_tex_image(const struct gl_texture_object *texObj,
370		                 GLenum target, GLint level)
371{
372   const GLuint face = _mesa_tex_target_to_face(target);
373
374   assert(texObj);
375   assert(level >= 0);
376   assert(level < MAX_TEXTURE_LEVELS);
377
378   return texObj->Image[face][level];
379}
380
381
382/**
383 * Like _mesa_select_tex_image() but if the image doesn't exist, allocate
384 * it and install it.  Only return NULL if passed a bad parameter or run
385 * out of memory.
386 */
387struct gl_texture_image *
388_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
389                    GLenum target, GLint level)
390{
391   struct gl_texture_image *texImage;
392
393   if (!texObj)
394      return NULL;
395
396   texImage = _mesa_select_tex_image(texObj, target, level);
397   if (!texImage) {
398      texImage = CALLOC_STRUCT(gl_texture_image);
399      if (!texImage) {
400         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation");
401         return NULL;
402      }
403
404      set_tex_image(texObj, target, level, texImage);
405   }
406
407   return texImage;
408}
409
410
411/**
412 * Return pointer to the specified proxy texture image.
413 * Note that proxy textures are per-context, not per-texture unit.
414 * \return pointer to texture image or NULL if invalid target, invalid
415 *         level, or out of memory.
416 */
417static struct gl_texture_image *
418get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
419{
420   struct gl_texture_image *texImage;
421   GLuint texIndex;
422
423   if (level < 0)
424      return NULL;
425
426   switch (target) {
427   case GL_PROXY_TEXTURE_1D:
428      texIndex = TEXTURE_1D_INDEX;
429      break;
430   case GL_PROXY_TEXTURE_2D:
431      texIndex = TEXTURE_2D_INDEX;
432      break;
433   case GL_PROXY_TEXTURE_3D:
434      texIndex = TEXTURE_3D_INDEX;
435      break;
436   case GL_PROXY_TEXTURE_CUBE_MAP:
437      texIndex = TEXTURE_CUBE_INDEX;
438      break;
439   case GL_PROXY_TEXTURE_RECTANGLE_NV:
440      if (level > 0)
441         return NULL;
442      texIndex = TEXTURE_RECT_INDEX;
443      break;
444   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
445      texIndex = TEXTURE_1D_ARRAY_INDEX;
446      break;
447   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
448      texIndex = TEXTURE_2D_ARRAY_INDEX;
449      break;
450   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
451      texIndex = TEXTURE_CUBE_ARRAY_INDEX;
452      break;
453   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
454      texIndex = TEXTURE_2D_MULTISAMPLE_INDEX;
455      break;
456   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
457      texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX;
458      break;
459   default:
460      return NULL;
461   }
462
463   texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level];
464   if (!texImage) {
465      texImage = CALLOC_STRUCT(gl_texture_image);
466      if (!texImage) {
467         _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation");
468         return NULL;
469      }
470      ctx->Texture.ProxyTex[texIndex]->Image[0][level] = texImage;
471      /* Set the 'back' pointer */
472      texImage->TexObject = ctx->Texture.ProxyTex[texIndex];
473   }
474   return texImage;
475}
476
477
478/**
479 * Get the maximum number of allowed mipmap levels.
480 *
481 * \param ctx GL context.
482 * \param target texture target.
483 *
484 * \return the maximum number of allowed mipmap levels for the given
485 * texture target, or zero if passed a bad target.
486 *
487 * \sa gl_constants.
488 */
489GLint
490_mesa_max_texture_levels(const struct gl_context *ctx, GLenum target)
491{
492   switch (target) {
493   case GL_TEXTURE_1D:
494   case GL_PROXY_TEXTURE_1D:
495   case GL_TEXTURE_2D:
496   case GL_PROXY_TEXTURE_2D:
497      return ffs(util_next_power_of_two(ctx->Const.MaxTextureSize));
498   case GL_TEXTURE_3D:
499   case GL_PROXY_TEXTURE_3D:
500      return !(ctx->API == API_OPENGLES2 && !ctx->Extensions.OES_texture_3D)
501         ? ctx->Const.Max3DTextureLevels : 0;
502   case GL_TEXTURE_CUBE_MAP:
503   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
504   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
505   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
506   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
507   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
508   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
509   case GL_PROXY_TEXTURE_CUBE_MAP:
510      return ctx->Const.MaxCubeTextureLevels;
511   case GL_TEXTURE_RECTANGLE_NV:
512   case GL_PROXY_TEXTURE_RECTANGLE_NV:
513      return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
514   case GL_TEXTURE_1D_ARRAY_EXT:
515   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
516   case GL_TEXTURE_2D_ARRAY_EXT:
517   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
518      return ctx->Extensions.EXT_texture_array
519         ? ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)) : 0;
520   case GL_TEXTURE_CUBE_MAP_ARRAY:
521   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
522      return _mesa_has_texture_cube_map_array(ctx)
523         ? ctx->Const.MaxCubeTextureLevels : 0;
524   case GL_TEXTURE_BUFFER:
525      return (_mesa_has_ARB_texture_buffer_object(ctx) ||
526              _mesa_has_OES_texture_buffer(ctx)) ? 1 : 0;
527   case GL_TEXTURE_2D_MULTISAMPLE:
528   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
529   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
530   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
531      return (_mesa_is_desktop_gl(ctx) || _mesa_is_gles31(ctx))
532         && ctx->Extensions.ARB_texture_multisample
533         ? 1 : 0;
534   case GL_TEXTURE_EXTERNAL_OES:
535      return _mesa_has_OES_EGL_image_external(ctx) ? 1 : 0;
536   default:
537      return 0; /* bad target */
538   }
539}
540
541
542/**
543 * Return number of dimensions per mipmap level for the given texture target.
544 */
545GLint
546_mesa_get_texture_dimensions(GLenum target)
547{
548   switch (target) {
549   case GL_TEXTURE_1D:
550   case GL_PROXY_TEXTURE_1D:
551      return 1;
552   case GL_TEXTURE_2D:
553   case GL_TEXTURE_RECTANGLE:
554   case GL_TEXTURE_CUBE_MAP:
555   case GL_PROXY_TEXTURE_2D:
556   case GL_PROXY_TEXTURE_RECTANGLE:
557   case GL_PROXY_TEXTURE_CUBE_MAP:
558   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
559   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
560   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
561   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
562   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
563   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
564   case GL_TEXTURE_1D_ARRAY:
565   case GL_PROXY_TEXTURE_1D_ARRAY:
566   case GL_TEXTURE_EXTERNAL_OES:
567   case GL_TEXTURE_2D_MULTISAMPLE:
568   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
569      return 2;
570   case GL_TEXTURE_3D:
571   case GL_PROXY_TEXTURE_3D:
572   case GL_TEXTURE_2D_ARRAY:
573   case GL_PROXY_TEXTURE_2D_ARRAY:
574   case GL_TEXTURE_CUBE_MAP_ARRAY:
575   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
576   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
577   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
578      return 3;
579   case GL_TEXTURE_BUFFER:
580      FALLTHROUGH;
581   default:
582      _mesa_problem(NULL, "invalid target 0x%x in get_texture_dimensions()",
583                    target);
584      return 2;
585   }
586}
587
588
589/**
590 * Check if a texture target can have more than one layer.
591 */
592GLboolean
593_mesa_tex_target_is_layered(GLenum target)
594{
595   switch (target) {
596   case GL_TEXTURE_1D:
597   case GL_PROXY_TEXTURE_1D:
598   case GL_TEXTURE_2D:
599   case GL_PROXY_TEXTURE_2D:
600   case GL_TEXTURE_RECTANGLE:
601   case GL_PROXY_TEXTURE_RECTANGLE:
602   case GL_TEXTURE_2D_MULTISAMPLE:
603   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
604   case GL_TEXTURE_BUFFER:
605   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
606   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
607   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
608   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
609   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
610   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
611   case GL_TEXTURE_EXTERNAL_OES:
612      return GL_FALSE;
613
614   case GL_TEXTURE_3D:
615   case GL_PROXY_TEXTURE_3D:
616   case GL_TEXTURE_CUBE_MAP:
617   case GL_PROXY_TEXTURE_CUBE_MAP:
618   case GL_TEXTURE_1D_ARRAY:
619   case GL_PROXY_TEXTURE_1D_ARRAY:
620   case GL_TEXTURE_2D_ARRAY:
621   case GL_PROXY_TEXTURE_2D_ARRAY:
622   case GL_TEXTURE_CUBE_MAP_ARRAY:
623   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
624   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
625   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
626      return GL_TRUE;
627
628   default:
629      assert(!"Invalid texture target.");
630      return GL_FALSE;
631   }
632}
633
634
635/**
636 * Return the number of layers present in the given level of an array,
637 * cubemap or 3D texture.  If the texture is not layered return zero.
638 */
639GLuint
640_mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level)
641{
642   assert(level >= 0 && level < MAX_TEXTURE_LEVELS);
643
644   switch (texObj->Target) {
645   case GL_TEXTURE_1D:
646   case GL_TEXTURE_2D:
647   case GL_TEXTURE_RECTANGLE:
648   case GL_TEXTURE_2D_MULTISAMPLE:
649   case GL_TEXTURE_BUFFER:
650   case GL_TEXTURE_EXTERNAL_OES:
651      return 0;
652
653   case GL_TEXTURE_CUBE_MAP:
654      return 6;
655
656   case GL_TEXTURE_1D_ARRAY: {
657      struct gl_texture_image *img = texObj->Image[0][level];
658      return img ? img->Height : 0;
659   }
660
661   case GL_TEXTURE_3D:
662   case GL_TEXTURE_2D_ARRAY:
663   case GL_TEXTURE_CUBE_MAP_ARRAY:
664   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: {
665      struct gl_texture_image *img = texObj->Image[0][level];
666      return img ? img->Depth : 0;
667   }
668
669   default:
670      assert(!"Invalid texture target.");
671      return 0;
672   }
673}
674
675
676/**
677 * Return the maximum number of mipmap levels for the given target
678 * and the dimensions.
679 * The dimensions are expected not to include the border.
680 */
681GLsizei
682_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height,
683                             GLsizei depth)
684{
685   GLsizei size;
686
687   switch (target) {
688   case GL_TEXTURE_1D:
689   case GL_TEXTURE_1D_ARRAY:
690   case GL_PROXY_TEXTURE_1D:
691   case GL_PROXY_TEXTURE_1D_ARRAY:
692      size = width;
693      break;
694   case GL_TEXTURE_CUBE_MAP:
695   case GL_TEXTURE_CUBE_MAP_ARRAY:
696   case GL_PROXY_TEXTURE_CUBE_MAP:
697   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
698      size = width;
699      break;
700   case GL_TEXTURE_2D:
701   case GL_TEXTURE_2D_ARRAY:
702   case GL_PROXY_TEXTURE_2D:
703   case GL_PROXY_TEXTURE_2D_ARRAY:
704      size = MAX2(width, height);
705      break;
706   case GL_TEXTURE_3D:
707   case GL_PROXY_TEXTURE_3D:
708      size = MAX3(width, height, depth);
709      break;
710   case GL_TEXTURE_RECTANGLE:
711   case GL_TEXTURE_EXTERNAL_OES:
712   case GL_TEXTURE_2D_MULTISAMPLE:
713   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
714   case GL_PROXY_TEXTURE_RECTANGLE:
715   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
716   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
717      return 1;
718   default:
719      assert(0);
720      return 1;
721   }
722
723   return util_logbase2(size) + 1;
724}
725
726
727#if 000 /* not used anymore */
728/*
729 * glTexImage[123]D can accept a NULL image pointer.  In this case we
730 * create a texture image with unspecified image contents per the OpenGL
731 * spec.
732 */
733static GLubyte *
734make_null_texture(GLint width, GLint height, GLint depth, GLenum format)
735{
736   const GLint components = _mesa_components_in_format(format);
737   const GLint numPixels = width * height * depth;
738   GLubyte *data = (GLubyte *) malloc(numPixels * components * sizeof(GLubyte));
739
740#ifdef DEBUG
741   /*
742    * Let's see if anyone finds this.  If glTexImage2D() is called with
743    * a NULL image pointer then load the texture image with something
744    * interesting instead of leaving it indeterminate.
745    */
746   if (data) {
747      static const char message[8][32] = {
748         "   X   X  XXXXX   XXX     X    ",
749         "   XX XX  X      X   X   X X   ",
750         "   X X X  X      X      X   X  ",
751         "   X   X  XXXX    XXX   XXXXX  ",
752         "   X   X  X          X  X   X  ",
753         "   X   X  X      X   X  X   X  ",
754         "   X   X  XXXXX   XXX   X   X  ",
755         "                               "
756      };
757
758      GLubyte *imgPtr = data;
759      GLint h, i, j, k;
760      for (h = 0; h < depth; h++) {
761         for (i = 0; i < height; i++) {
762            GLint srcRow = 7 - (i % 8);
763            for (j = 0; j < width; j++) {
764               GLint srcCol = j % 32;
765               GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
766               for (k = 0; k < components; k++) {
767                  *imgPtr++ = texel;
768               }
769            }
770         }
771      }
772   }
773#endif
774
775   return data;
776}
777#endif
778
779
780
781/**
782 * Set the size and format-related fields of a gl_texture_image struct
783 * to zero.  This is used when a proxy texture test fails.
784 */
785static void
786clear_teximage_fields(struct gl_texture_image *img)
787{
788   assert(img);
789   img->_BaseFormat = 0;
790   img->InternalFormat = 0;
791   img->Border = 0;
792   img->Width = 0;
793   img->Height = 0;
794   img->Depth = 0;
795   img->Width2 = 0;
796   img->Height2 = 0;
797   img->Depth2 = 0;
798   img->WidthLog2 = 0;
799   img->HeightLog2 = 0;
800   img->DepthLog2 = 0;
801   img->TexFormat = MESA_FORMAT_NONE;
802   img->NumSamples = 0;
803   img->FixedSampleLocations = GL_TRUE;
804}
805
806
807/**
808 * Initialize basic fields of the gl_texture_image struct.
809 *
810 * \param ctx GL context.
811 * \param img texture image structure to be initialized.
812 * \param width image width.
813 * \param height image height.
814 * \param depth image depth.
815 * \param border image border.
816 * \param internalFormat internal format.
817 * \param format  the actual hardware format (one of MESA_FORMAT_*)
818 * \param numSamples  number of samples per texel, or zero for non-MS.
819 * \param fixedSampleLocations  are sample locations fixed?
820 *
821 * Fills in the fields of \p img with the given information.
822 * Note: width, height and depth include the border.
823 */
824void
825_mesa_init_teximage_fields_ms(struct gl_context *ctx,
826                        struct gl_texture_image *img,
827                        GLsizei width, GLsizei height, GLsizei depth,
828                        GLint border, GLenum internalFormat,
829                        mesa_format format,
830                        GLuint numSamples, GLboolean fixedSampleLocations)
831{
832   const GLint base_format =_mesa_base_tex_format(ctx, internalFormat);
833   GLenum target;
834   assert(img);
835   assert(width >= 0);
836   assert(height >= 0);
837   assert(depth >= 0);
838
839   target = img->TexObject->Target;
840   assert(base_format != -1);
841   img->_BaseFormat = (GLenum16)base_format;
842   img->InternalFormat = internalFormat;
843   img->Border = border;
844   img->Width = width;
845   img->Height = height;
846   img->Depth = depth;
847
848   img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
849   img->WidthLog2 = util_logbase2(img->Width2);
850
851   switch(target) {
852   case GL_TEXTURE_1D:
853   case GL_TEXTURE_BUFFER:
854   case GL_PROXY_TEXTURE_1D:
855      if (height == 0)
856         img->Height2 = 0;
857      else
858         img->Height2 = 1;
859      img->HeightLog2 = 0;
860      if (depth == 0)
861         img->Depth2 = 0;
862      else
863         img->Depth2 = 1;
864      img->DepthLog2 = 0;
865      break;
866   case GL_TEXTURE_1D_ARRAY:
867   case GL_PROXY_TEXTURE_1D_ARRAY:
868      img->Height2 = height; /* no border */
869      img->HeightLog2 = 0; /* not used */
870      if (depth == 0)
871         img->Depth2 = 0;
872      else
873         img->Depth2 = 1;
874      img->DepthLog2 = 0;
875      break;
876   case GL_TEXTURE_2D:
877   case GL_TEXTURE_RECTANGLE:
878   case GL_TEXTURE_CUBE_MAP:
879   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
880   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
881   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
882   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
883   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
884   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
885   case GL_TEXTURE_EXTERNAL_OES:
886   case GL_PROXY_TEXTURE_2D:
887   case GL_PROXY_TEXTURE_RECTANGLE:
888   case GL_PROXY_TEXTURE_CUBE_MAP:
889   case GL_TEXTURE_2D_MULTISAMPLE:
890   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
891      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
892      img->HeightLog2 = util_logbase2(img->Height2);
893      if (depth == 0)
894         img->Depth2 = 0;
895      else
896         img->Depth2 = 1;
897      img->DepthLog2 = 0;
898      break;
899   case GL_TEXTURE_2D_ARRAY:
900   case GL_PROXY_TEXTURE_2D_ARRAY:
901   case GL_TEXTURE_CUBE_MAP_ARRAY:
902   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
903   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
904   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
905      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
906      img->HeightLog2 = util_logbase2(img->Height2);
907      img->Depth2 = depth; /* no border */
908      img->DepthLog2 = 0; /* not used */
909      break;
910   case GL_TEXTURE_3D:
911   case GL_PROXY_TEXTURE_3D:
912      img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
913      img->HeightLog2 = util_logbase2(img->Height2);
914      img->Depth2 = depth - 2 * border;   /* == 1 << img->DepthLog2; */
915      img->DepthLog2 = util_logbase2(img->Depth2);
916      break;
917   default:
918      _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()",
919                    target);
920   }
921
922   img->MaxNumLevels =
923      _mesa_get_tex_max_num_levels(target,
924                                   img->Width2, img->Height2, img->Depth2);
925   img->TexFormat = format;
926   img->NumSamples = numSamples;
927   img->FixedSampleLocations = fixedSampleLocations;
928}
929
930
931void
932_mesa_init_teximage_fields(struct gl_context *ctx,
933                           struct gl_texture_image *img,
934                           GLsizei width, GLsizei height, GLsizei depth,
935                           GLint border, GLenum internalFormat,
936                           mesa_format format)
937{
938   _mesa_init_teximage_fields_ms(ctx, img, width, height, depth, border,
939                                 internalFormat, format, 0, GL_TRUE);
940}
941
942
943/**
944 * Free and clear fields of the gl_texture_image struct.
945 *
946 * \param ctx GL context.
947 * \param texImage texture image structure to be cleared.
948 *
949 * After the call, \p texImage will have no data associated with it.  Its
950 * fields are cleared so that its parent object will test incomplete.
951 */
952void
953_mesa_clear_texture_image(struct gl_context *ctx,
954                          struct gl_texture_image *texImage)
955{
956   st_FreeTextureImageBuffer(ctx, texImage);
957   clear_teximage_fields(texImage);
958}
959
960
961/**
962 * Check the width, height, depth and border of a texture image are legal.
963 * Used by all the glTexImage, glCompressedTexImage and glCopyTexImage
964 * functions.
965 * The target and level parameters will have already been validated.
966 * \return GL_TRUE if size is OK, GL_FALSE otherwise.
967 */
968GLboolean
969_mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
970                               GLint level, GLint width, GLint height,
971                               GLint depth, GLint border)
972{
973   GLint maxSize;
974
975   switch (target) {
976   case GL_TEXTURE_1D:
977   case GL_PROXY_TEXTURE_1D:
978      maxSize = ctx->Const.MaxTextureSize >> level;
979      if (width < 2 * border || width > 2 * border + maxSize)
980         return GL_FALSE;
981      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
982         if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
983            return GL_FALSE;
984      }
985      return GL_TRUE;
986
987   case GL_TEXTURE_2D:
988   case GL_PROXY_TEXTURE_2D:
989   case GL_TEXTURE_2D_MULTISAMPLE:
990   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
991      maxSize = ctx->Const.MaxTextureSize >> level;
992      if (width < 2 * border || width > 2 * border + maxSize)
993         return GL_FALSE;
994      if (height < 2 * border || height > 2 * border + maxSize)
995         return GL_FALSE;
996      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
997         if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
998            return GL_FALSE;
999         if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1000            return GL_FALSE;
1001      }
1002      return GL_TRUE;
1003
1004   case GL_TEXTURE_3D:
1005   case GL_PROXY_TEXTURE_3D:
1006      maxSize = 1 << (ctx->Const.Max3DTextureLevels - 1);
1007      maxSize >>= level;
1008      if (width < 2 * border || width > 2 * border + maxSize)
1009         return GL_FALSE;
1010      if (height < 2 * border || height > 2 * border + maxSize)
1011         return GL_FALSE;
1012      if (depth < 2 * border || depth > 2 * border + maxSize)
1013         return GL_FALSE;
1014      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1015         if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1016            return GL_FALSE;
1017         if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1018            return GL_FALSE;
1019         if (depth > 0 && !util_is_power_of_two_nonzero(depth - 2 * border))
1020            return GL_FALSE;
1021      }
1022      return GL_TRUE;
1023
1024   case GL_TEXTURE_RECTANGLE_NV:
1025   case GL_PROXY_TEXTURE_RECTANGLE_NV:
1026      if (level != 0)
1027         return GL_FALSE;
1028      maxSize = ctx->Const.MaxTextureRectSize;
1029      if (width < 0 || width > maxSize)
1030         return GL_FALSE;
1031      if (height < 0 || height > maxSize)
1032         return GL_FALSE;
1033      return GL_TRUE;
1034
1035   case GL_TEXTURE_CUBE_MAP:
1036   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1037   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1038   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1039   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1040   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1041   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1042   case GL_PROXY_TEXTURE_CUBE_MAP:
1043      maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
1044      maxSize >>= level;
1045      if (width != height)
1046         return GL_FALSE;
1047      if (width < 2 * border || width > 2 * border + maxSize)
1048         return GL_FALSE;
1049      if (height < 2 * border || height > 2 * border + maxSize)
1050         return GL_FALSE;
1051      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1052         if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1053            return GL_FALSE;
1054         if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1055            return GL_FALSE;
1056      }
1057      return GL_TRUE;
1058
1059   case GL_TEXTURE_1D_ARRAY_EXT:
1060   case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1061      maxSize = ctx->Const.MaxTextureSize >> level;
1062      if (width < 2 * border || width > 2 * border + maxSize)
1063         return GL_FALSE;
1064      if (height < 0 || height > ctx->Const.MaxArrayTextureLayers)
1065         return GL_FALSE;
1066      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1067         if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1068            return GL_FALSE;
1069      }
1070      return GL_TRUE;
1071
1072   case GL_TEXTURE_2D_ARRAY_EXT:
1073   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1074   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
1075   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
1076      maxSize = ctx->Const.MaxTextureSize >> level;
1077      if (width < 2 * border || width > 2 * border + maxSize)
1078         return GL_FALSE;
1079      if (height < 2 * border || height > 2 * border + maxSize)
1080         return GL_FALSE;
1081      if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers)
1082         return GL_FALSE;
1083      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1084         if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1085            return GL_FALSE;
1086         if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1087            return GL_FALSE;
1088      }
1089      return GL_TRUE;
1090
1091   case GL_TEXTURE_CUBE_MAP_ARRAY:
1092   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1093      maxSize = 1 << (ctx->Const.MaxCubeTextureLevels - 1);
1094      if (width < 2 * border || width > 2 * border + maxSize)
1095         return GL_FALSE;
1096      if (height < 2 * border || height > 2 * border + maxSize)
1097         return GL_FALSE;
1098      if (depth < 0 || depth > ctx->Const.MaxArrayTextureLayers || depth % 6)
1099         return GL_FALSE;
1100      if (width != height)
1101         return GL_FALSE;
1102      if (level >= ctx->Const.MaxCubeTextureLevels)
1103         return GL_FALSE;
1104      if (!ctx->Extensions.ARB_texture_non_power_of_two) {
1105         if (width > 0 && !util_is_power_of_two_nonzero(width - 2 * border))
1106            return GL_FALSE;
1107         if (height > 0 && !util_is_power_of_two_nonzero(height - 2 * border))
1108            return GL_FALSE;
1109      }
1110      return GL_TRUE;
1111   default:
1112      _mesa_problem(ctx, "Invalid target in _mesa_legal_texture_dimensions()");
1113      return GL_FALSE;
1114   }
1115}
1116
1117static bool
1118error_check_subtexture_negative_dimensions(struct gl_context *ctx,
1119                                           GLuint dims,
1120                                           GLsizei subWidth,
1121                                           GLsizei subHeight,
1122                                           GLsizei subDepth,
1123                                           const char *func)
1124{
1125   /* Check size */
1126   if (subWidth < 0) {
1127      _mesa_error(ctx, GL_INVALID_VALUE, "%s(width=%d)", func, subWidth);
1128      return true;
1129   }
1130
1131   if (dims > 1 && subHeight < 0) {
1132      _mesa_error(ctx, GL_INVALID_VALUE, "%s(height=%d)", func, subHeight);
1133      return true;
1134   }
1135
1136   if (dims > 2 && subDepth < 0) {
1137      _mesa_error(ctx, GL_INVALID_VALUE, "%s(depth=%d)", func, subDepth);
1138      return true;
1139   }
1140
1141   return false;
1142}
1143
1144/**
1145 * Do error checking of xoffset, yoffset, zoffset, width, height and depth
1146 * for glTexSubImage, glCopyTexSubImage and glCompressedTexSubImage.
1147 * \param destImage  the destination texture image.
1148 * \return GL_TRUE if error found, GL_FALSE otherwise.
1149 */
1150static GLboolean
1151error_check_subtexture_dimensions(struct gl_context *ctx, GLuint dims,
1152                                  const struct gl_texture_image *destImage,
1153                                  GLint xoffset, GLint yoffset, GLint zoffset,
1154                                  GLsizei subWidth, GLsizei subHeight,
1155                                  GLsizei subDepth, const char *func)
1156{
1157   const GLenum target = destImage->TexObject->Target;
1158   GLuint bw, bh, bd;
1159
1160   /* check xoffset and width */
1161   if (xoffset < - (GLint) destImage->Border) {
1162      _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset)", func);
1163      return GL_TRUE;
1164   }
1165
1166   if (xoffset + subWidth > (GLint) destImage->Width) {
1167      _mesa_error(ctx, GL_INVALID_VALUE, "%s(xoffset %d + width %d > %u)", func,
1168                  xoffset, subWidth, destImage->Width);
1169      return GL_TRUE;
1170   }
1171
1172   /* check yoffset and height */
1173   if (dims > 1) {
1174      GLint yBorder = (target == GL_TEXTURE_1D_ARRAY) ? 0 : destImage->Border;
1175      if (yoffset < -yBorder) {
1176         _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset)", func);
1177         return GL_TRUE;
1178      }
1179      if (yoffset + subHeight > (GLint) destImage->Height) {
1180         _mesa_error(ctx, GL_INVALID_VALUE, "%s(yoffset %d + height %d > %u)",
1181                     func, yoffset, subHeight, destImage->Height);
1182         return GL_TRUE;
1183      }
1184   }
1185
1186   /* check zoffset and depth */
1187   if (dims > 2) {
1188      GLint depth;
1189      GLint zBorder = (target == GL_TEXTURE_2D_ARRAY ||
1190                       target == GL_TEXTURE_CUBE_MAP_ARRAY) ?
1191                         0 : destImage->Border;
1192
1193      if (zoffset < -zBorder) {
1194         _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset)", func);
1195         return GL_TRUE;
1196      }
1197
1198      depth = (GLint) destImage->Depth;
1199      if (target == GL_TEXTURE_CUBE_MAP)
1200         depth = 6;
1201      if (zoffset + subDepth  > depth) {
1202         _mesa_error(ctx, GL_INVALID_VALUE, "%s(zoffset %d + depth %d > %u)",
1203                     func, zoffset, subDepth, depth);
1204         return GL_TRUE;
1205      }
1206   }
1207
1208   /*
1209    * The OpenGL spec (and GL_ARB_texture_compression) says only whole
1210    * compressed texture images can be updated.  But, that restriction may be
1211    * relaxed for particular compressed formats.  At this time, all the
1212    * compressed formats supported by Mesa allow sub-textures to be updated
1213    * along compressed block boundaries.
1214    */
1215   _mesa_get_format_block_size_3d(destImage->TexFormat, &bw, &bh, &bd);
1216
1217   if (bw != 1 || bh != 1 || bd != 1) {
1218      /* offset must be multiple of block size */
1219      if ((xoffset % bw != 0) || (yoffset % bh != 0) || (zoffset % bd != 0)) {
1220         _mesa_error(ctx, GL_INVALID_OPERATION,
1221                     "%s(xoffset = %d, yoffset = %d, zoffset = %d)",
1222                     func, xoffset, yoffset, zoffset);
1223         return GL_TRUE;
1224      }
1225
1226      /* The size must be a multiple of bw x bh, or we must be using a
1227       * offset+size that exactly hits the edge of the image.  This
1228       * is important for small mipmap levels (1x1, 2x1, etc) and for
1229       * NPOT textures.
1230       */
1231      if ((subWidth % bw != 0) &&
1232          (xoffset + subWidth != (GLint) destImage->Width)) {
1233         _mesa_error(ctx, GL_INVALID_OPERATION,
1234                     "%s(width = %d)", func, subWidth);
1235         return GL_TRUE;
1236      }
1237
1238      if ((subHeight % bh != 0) &&
1239          (yoffset + subHeight != (GLint) destImage->Height)) {
1240         _mesa_error(ctx, GL_INVALID_OPERATION,
1241                     "%s(height = %d)", func, subHeight);
1242         return GL_TRUE;
1243      }
1244
1245      if ((subDepth % bd != 0) &&
1246          (zoffset + subDepth != (GLint) destImage->Depth)) {
1247         _mesa_error(ctx, GL_INVALID_OPERATION,
1248                     "%s(depth = %d)", func, subDepth);
1249         return GL_TRUE;
1250      }
1251   }
1252
1253   return GL_FALSE;
1254}
1255
1256
1257
1258
1259/**
1260 * This is the fallback for Driver.TestProxyTexImage() for doing device-
1261 * specific texture image size checks.
1262 *
1263 * A hardware driver might override this function if, for example, the
1264 * max 3D texture size is 512x512x64 (i.e. not a cube).
1265 *
1266 * Note that width, height, depth == 0 is not an error.  However, a
1267 * texture with zero width/height/depth will be considered "incomplete"
1268 * and texturing will effectively be disabled.
1269 *
1270 * \param target  any texture target/type
1271 * \param numLevels  number of mipmap levels in the texture or 0 if not known
1272 * \param level  as passed to glTexImage
1273 * \param format  the MESA_FORMAT_x for the tex image
1274 * \param numSamples  number of samples per texel
1275 * \param width  as passed to glTexImage
1276 * \param height  as passed to glTexImage
1277 * \param depth  as passed to glTexImage
1278 * \return GL_TRUE if the image is acceptable, GL_FALSE if not acceptable.
1279 */
1280GLboolean
1281_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target,
1282                          GLuint numLevels, ASSERTED GLint level,
1283                          mesa_format format, GLuint numSamples,
1284                          GLint width, GLint height, GLint depth)
1285{
1286   uint64_t bytes, mbytes;
1287
1288   if (numLevels > 0) {
1289      /* Compute total memory for a whole mipmap.  This is the path
1290       * taken for glTexStorage(GL_PROXY_TEXTURE_x).
1291       */
1292      unsigned l;
1293
1294      assert(level == 0);
1295
1296      bytes = 0;
1297
1298      for (l = 0; l < numLevels; l++) {
1299         GLint nextWidth, nextHeight, nextDepth;
1300
1301         bytes += _mesa_format_image_size64(format, width, height, depth);
1302
1303         if (_mesa_next_mipmap_level_size(target, 0, width, height, depth,
1304                                          &nextWidth, &nextHeight,
1305                                          &nextDepth)) {
1306            width = nextWidth;
1307            height = nextHeight;
1308            depth = nextDepth;
1309         } else {
1310            break;
1311         }
1312      }
1313   } else {
1314      /* We just compute the size of one mipmap level.  This is the path
1315       * taken for glTexImage(GL_PROXY_TEXTURE_x).
1316       */
1317      bytes = _mesa_format_image_size64(format, width, height, depth);
1318   }
1319
1320   bytes *= _mesa_num_tex_faces(target);
1321   bytes *= MAX2(1, numSamples);
1322
1323   mbytes = bytes / (1024 * 1024); /* convert to MB */
1324
1325   /* We just check if the image size is less than MaxTextureMbytes.
1326    * Some drivers may do more specific checks.
1327    */
1328   return mbytes <= (uint64_t) ctx->Const.MaxTextureMbytes;
1329}
1330
1331
1332/**
1333 * Return true if the format is only valid for glCompressedTexImage.
1334 */
1335static bool
1336compressedteximage_only_format(GLenum format)
1337{
1338   switch (format) {
1339   case GL_PALETTE4_RGB8_OES:
1340   case GL_PALETTE4_RGBA8_OES:
1341   case GL_PALETTE4_R5_G6_B5_OES:
1342   case GL_PALETTE4_RGBA4_OES:
1343   case GL_PALETTE4_RGB5_A1_OES:
1344   case GL_PALETTE8_RGB8_OES:
1345   case GL_PALETTE8_RGBA8_OES:
1346   case GL_PALETTE8_R5_G6_B5_OES:
1347   case GL_PALETTE8_RGBA4_OES:
1348   case GL_PALETTE8_RGB5_A1_OES:
1349   case GL_ATC_RGB_AMD:
1350   case GL_ATC_RGBA_EXPLICIT_ALPHA_AMD:
1351   case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
1352      return true;
1353   default:
1354      return false;
1355   }
1356}
1357
1358/**
1359 * Return true if the format doesn't support online compression.
1360 */
1361bool
1362_mesa_format_no_online_compression(GLenum format)
1363{
1364   return _mesa_is_astc_format(format) ||
1365          _mesa_is_etc2_format(format) ||
1366          compressedteximage_only_format(format);
1367}
1368
1369/* Writes to an GL error pointer if non-null and returns whether or not the
1370 * error is GL_NO_ERROR */
1371static bool
1372write_error(GLenum *err_ptr, GLenum error)
1373{
1374   if (err_ptr)
1375      *err_ptr = error;
1376
1377   return error == GL_NO_ERROR;
1378}
1379
1380/**
1381 * Helper function to determine whether a target and specific compression
1382 * format are supported. The error parameter returns GL_NO_ERROR if the
1383 * target can be compressed. Otherwise it returns either GL_INVALID_OPERATION
1384 * or GL_INVALID_ENUM, whichever is more appropriate.
1385 */
1386GLboolean
1387_mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target,
1388                               GLenum intFormat, GLenum *error)
1389{
1390   GLboolean target_can_be_compresed = GL_FALSE;
1391   mesa_format format = _mesa_glenum_to_compressed_format(intFormat);
1392   enum mesa_format_layout layout = _mesa_get_format_layout(format);
1393
1394   switch (target) {
1395   case GL_TEXTURE_2D:
1396   case GL_PROXY_TEXTURE_2D:
1397      target_can_be_compresed = GL_TRUE; /* true for any compressed format so far */
1398      break;
1399   case GL_PROXY_TEXTURE_CUBE_MAP:
1400   case GL_TEXTURE_CUBE_MAP:
1401   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1402   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1403   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1404   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1405   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1406   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1407      target_can_be_compresed = GL_TRUE;
1408      break;
1409   case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1410   case GL_TEXTURE_2D_ARRAY_EXT:
1411      target_can_be_compresed = ctx->Extensions.EXT_texture_array;
1412      break;
1413   case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1414   case GL_TEXTURE_CUBE_MAP_ARRAY:
1415      /* From the KHR_texture_compression_astc_hdr spec:
1416       *
1417       *     Add a second new column "3D Tex." which is empty for all non-ASTC
1418       *     formats. If only the LDR profile is supported by the
1419       *     implementation, this column is also empty for all ASTC formats. If
1420       *     both the LDR and HDR profiles are supported only, this column is
1421       *     checked for all ASTC formats.
1422       *
1423       *     Add a third new column "Cube Map Array Tex." which is empty for all
1424       *     non-ASTC formats, and checked for all ASTC formats.
1425       *
1426       * and,
1427       *
1428       *     'An INVALID_OPERATION error is generated by CompressedTexImage3D
1429       *      if <internalformat> is TEXTURE_CUBE_MAP_ARRAY and the
1430       *      "Cube Map Array" column of table 8.19 is *not* checked, or if
1431       *      <internalformat> is TEXTURE_3D and the "3D Tex." column of table
1432       *      8.19 is *not* checked'
1433       *
1434       * The instances of <internalformat> above should say <target>.
1435       *
1436       * ETC2/EAC formats are the only alternative in GLES and thus such errors
1437       * have already been handled by normal ETC2/EAC behavior.
1438       */
1439
1440      /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
1441       *
1442       *    "The ETC2/EAC texture compression algorithm supports only
1443       *     two-dimensional images. If internalformat is an ETC2/EAC format,
1444       *     glCompressedTexImage3D will generate an INVALID_OPERATION error if
1445       *     target is not TEXTURE_2D_ARRAY."
1446       *
1447       * This should also be applicable for glTexStorage3D(). Other available
1448       * targets for these functions are: TEXTURE_3D and TEXTURE_CUBE_MAP_ARRAY.
1449       *
1450       * Section 8.7, page 179 of OpenGL ES 3.2 adds:
1451       *
1452       *      An INVALID_OPERATION error is generated by CompressedTexImage3D
1453       *      if internalformat is one of the the formats in table 8.17 and target is
1454       *      not TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY or TEXTURE_3D.
1455       *
1456       *      An INVALID_OPERATION error is generated by CompressedTexImage3D
1457       *      if internalformat is TEXTURE_CUBE_MAP_ARRAY and the “Cube Map
1458       *      Array” column of table 8.17 is not checked, or if internalformat
1459       *      is TEXTURE_- 3D and the “3D Tex.” column of table 8.17 is not
1460       *      checked.
1461       *
1462       * The instances of <internalformat> above should say <target>.
1463       *
1464       * Such table 8.17 has checked "Cube Map Array" column for all the
1465       * cases. So in practice, TEXTURE_CUBE_MAP_ARRAY is now valid for OpenGL ES 3.2
1466       */
1467      if (layout == MESA_FORMAT_LAYOUT_ETC2 && _mesa_is_gles3(ctx) &&
1468          !_mesa_is_gles32(ctx))
1469            return write_error(error, GL_INVALID_OPERATION);
1470      target_can_be_compresed = _mesa_has_texture_cube_map_array(ctx);
1471      break;
1472   case GL_TEXTURE_3D:
1473      switch (layout) {
1474      case MESA_FORMAT_LAYOUT_ETC2:
1475         /* See ETC2/EAC comment in case GL_TEXTURE_CUBE_MAP_ARRAY. */
1476         if (_mesa_is_gles3(ctx))
1477            return write_error(error, GL_INVALID_OPERATION);
1478         break;
1479      case MESA_FORMAT_LAYOUT_BPTC:
1480         target_can_be_compresed = ctx->Extensions.ARB_texture_compression_bptc;
1481         break;
1482      case MESA_FORMAT_LAYOUT_ASTC:
1483         target_can_be_compresed =
1484            ctx->Extensions.KHR_texture_compression_astc_hdr ||
1485            ctx->Extensions.KHR_texture_compression_astc_sliced_3d;
1486
1487         /* Throw an INVALID_OPERATION error if the target is TEXTURE_3D and
1488          * neither of the above extensions are supported. See comment in
1489          * switch case GL_TEXTURE_CUBE_MAP_ARRAY for more info.
1490          */
1491         if (!target_can_be_compresed)
1492            return write_error(error, GL_INVALID_OPERATION);
1493         break;
1494      default:
1495         break;
1496      }
1497      FALLTHROUGH;
1498   default:
1499      break;
1500   }
1501   return write_error(error,
1502                      target_can_be_compresed ? GL_NO_ERROR : GL_INVALID_ENUM);
1503}
1504
1505
1506/**
1507 * Check if the given texture target value is legal for a
1508 * glTexImage1/2/3D call.
1509 */
1510static GLboolean
1511legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target)
1512{
1513   switch (dims) {
1514   case 1:
1515      switch (target) {
1516      case GL_TEXTURE_1D:
1517      case GL_PROXY_TEXTURE_1D:
1518         return _mesa_is_desktop_gl(ctx);
1519      default:
1520         return GL_FALSE;
1521      }
1522   case 2:
1523      switch (target) {
1524      case GL_TEXTURE_2D:
1525         return GL_TRUE;
1526      case GL_PROXY_TEXTURE_2D:
1527         return _mesa_is_desktop_gl(ctx);
1528      case GL_PROXY_TEXTURE_CUBE_MAP:
1529         return _mesa_is_desktop_gl(ctx);
1530      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1531      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1532      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1533      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1534      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1535      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1536         return GL_TRUE;
1537      case GL_TEXTURE_RECTANGLE_NV:
1538      case GL_PROXY_TEXTURE_RECTANGLE_NV:
1539         return _mesa_is_desktop_gl(ctx)
1540            && ctx->Extensions.NV_texture_rectangle;
1541      case GL_TEXTURE_1D_ARRAY_EXT:
1542      case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
1543         return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
1544      default:
1545         return GL_FALSE;
1546      }
1547   case 3:
1548      switch (target) {
1549      case GL_TEXTURE_3D:
1550         return GL_TRUE;
1551      case GL_PROXY_TEXTURE_3D:
1552         return _mesa_is_desktop_gl(ctx);
1553      case GL_TEXTURE_2D_ARRAY_EXT:
1554         return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array)
1555            || _mesa_is_gles3(ctx);
1556      case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
1557         return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
1558      case GL_TEXTURE_CUBE_MAP_ARRAY:
1559      case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1560         return _mesa_has_texture_cube_map_array(ctx);
1561      default:
1562         return GL_FALSE;
1563      }
1564   default:
1565      _mesa_problem(ctx, "invalid dims=%u in legal_teximage_target()", dims);
1566      return GL_FALSE;
1567   }
1568}
1569
1570
1571/**
1572 * Check if the given texture target value is legal for a
1573 * glTexSubImage, glCopyTexSubImage or glCopyTexImage call.
1574 * The difference compared to legal_teximage_target() above is that
1575 * proxy targets are not supported.
1576 */
1577static GLboolean
1578legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target,
1579                         bool dsa)
1580{
1581   switch (dims) {
1582   case 1:
1583      return _mesa_is_desktop_gl(ctx) && target == GL_TEXTURE_1D;
1584   case 2:
1585      switch (target) {
1586      case GL_TEXTURE_2D:
1587         return GL_TRUE;
1588      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1589      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1590      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1591      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1592      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1593      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1594         return GL_TRUE;
1595      case GL_TEXTURE_RECTANGLE_NV:
1596         return _mesa_is_desktop_gl(ctx)
1597            && ctx->Extensions.NV_texture_rectangle;
1598      case GL_TEXTURE_1D_ARRAY_EXT:
1599         return _mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array;
1600      default:
1601         return GL_FALSE;
1602      }
1603   case 3:
1604      switch (target) {
1605      case GL_TEXTURE_3D:
1606         return GL_TRUE;
1607      case GL_TEXTURE_2D_ARRAY_EXT:
1608         return (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array)
1609            || _mesa_is_gles3(ctx);
1610      case GL_TEXTURE_CUBE_MAP_ARRAY:
1611      case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
1612         return _mesa_has_texture_cube_map_array(ctx);
1613
1614      /* Table 8.15 of the OpenGL 4.5 core profile spec
1615       * (20141030) says that TEXTURE_CUBE_MAP is valid for TextureSubImage3D
1616       * and CopyTextureSubImage3D.
1617       */
1618      case GL_TEXTURE_CUBE_MAP:
1619         return dsa;
1620      default:
1621         return GL_FALSE;
1622      }
1623   default:
1624      _mesa_problem(ctx, "invalid dims=%u in legal_texsubimage_target()",
1625                    dims);
1626      return GL_FALSE;
1627   }
1628}
1629
1630
1631/**
1632 * Helper function to determine if a texture object is mutable (in terms
1633 * of GL_ARB_texture_storage/GL_ARB_bindless_texture).
1634 */
1635static GLboolean
1636mutable_tex_object(struct gl_texture_object *texObj)
1637{
1638   if (!texObj)
1639      return GL_FALSE;
1640
1641   if (texObj->HandleAllocated) {
1642      /* The ARB_bindless_texture spec says:
1643       *
1644       * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
1645       *  CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
1646       *  functions defined in terms of these, if the texture object to be
1647       *  modified is referenced by one or more texture or image handles."
1648       */
1649      return GL_FALSE;
1650   }
1651
1652   return !texObj->Immutable;
1653}
1654
1655
1656/**
1657 * Return expected size of a compressed texture.
1658 */
1659static GLuint
1660compressed_tex_size(GLsizei width, GLsizei height, GLsizei depth,
1661                    GLenum glformat)
1662{
1663   mesa_format mesaFormat = _mesa_glenum_to_compressed_format(glformat);
1664   return _mesa_format_image_size(mesaFormat, width, height, depth);
1665}
1666
1667/**
1668 * Verify that a texture format is valid with a particular target
1669 *
1670 * In particular, textures with base format of \c GL_DEPTH_COMPONENT or
1671 * \c GL_DEPTH_STENCIL are only valid with certain, context dependent texture
1672 * targets.
1673 *
1674 * \param ctx             GL context
1675 * \param target          Texture target
1676 * \param internalFormat  Internal format of the texture image
1677 *
1678 * \returns true if the combination is legal, false otherwise.
1679 */
1680bool
1681_mesa_legal_texture_base_format_for_target(struct gl_context *ctx,
1682                                           GLenum target, GLenum internalFormat)
1683{
1684   if (_mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_COMPONENT
1685       || _mesa_base_tex_format(ctx, internalFormat) == GL_DEPTH_STENCIL
1686       || _mesa_base_tex_format(ctx, internalFormat) == GL_STENCIL_INDEX) {
1687      /* Section 3.8.3 (Texture Image Specification) of the OpenGL 3.3 Core
1688       * Profile spec says:
1689       *
1690       *     "Textures with a base internal format of DEPTH_COMPONENT or
1691       *     DEPTH_STENCIL are supported by texture image specification
1692       *     commands only if target is TEXTURE_1D, TEXTURE_2D,
1693       *     TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_RECTANGLE,
1694       *     TEXTURE_CUBE_MAP, PROXY_TEXTURE_1D, PROXY_TEXTURE_2D,
1695       *     PROXY_TEXTURE_1D_ARRAY, PROXY_TEXTURE_2D_ARRAY,
1696       *     PROXY_TEXTURE_RECTANGLE, or PROXY_TEXTURE_CUBE_MAP. Using these
1697       *     formats in conjunction with any other target will result in an
1698       *     INVALID_OPERATION error."
1699       *
1700       * Cubemaps are only supported with desktop OpenGL version >= 3.0,
1701       * EXT_gpu_shader4, or, on OpenGL ES 2.0+, OES_depth_texture_cube_map.
1702       */
1703      if (target != GL_TEXTURE_1D &&
1704          target != GL_PROXY_TEXTURE_1D &&
1705          target != GL_TEXTURE_2D &&
1706          target != GL_PROXY_TEXTURE_2D &&
1707          target != GL_TEXTURE_1D_ARRAY &&
1708          target != GL_PROXY_TEXTURE_1D_ARRAY &&
1709          target != GL_TEXTURE_2D_ARRAY &&
1710          target != GL_PROXY_TEXTURE_2D_ARRAY &&
1711          target != GL_TEXTURE_RECTANGLE_ARB &&
1712          target != GL_PROXY_TEXTURE_RECTANGLE_ARB &&
1713         !((_mesa_is_cube_face(target) ||
1714            target == GL_TEXTURE_CUBE_MAP ||
1715            target == GL_PROXY_TEXTURE_CUBE_MAP) &&
1716           (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4
1717            || (ctx->API == API_OPENGLES2 && ctx->Extensions.OES_depth_texture_cube_map))) &&
1718          !((target == GL_TEXTURE_CUBE_MAP_ARRAY ||
1719             target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) &&
1720            _mesa_has_texture_cube_map_array(ctx))) {
1721         return false;
1722      }
1723   }
1724
1725   return true;
1726}
1727
1728static bool
1729texture_formats_agree(GLenum internalFormat,
1730                      GLenum format)
1731{
1732   GLboolean colorFormat;
1733   GLboolean is_format_depth_or_depthstencil;
1734   GLboolean is_internalFormat_depth_or_depthstencil;
1735
1736   /* Even though there are no color-index textures, we still have to support
1737    * uploading color-index data and remapping it to RGB via the
1738    * GL_PIXEL_MAP_I_TO_[RGBA] tables.
1739    */
1740   const GLboolean indexFormat = (format == GL_COLOR_INDEX);
1741
1742   is_internalFormat_depth_or_depthstencil =
1743      _mesa_is_depth_format(internalFormat) ||
1744      _mesa_is_depthstencil_format(internalFormat);
1745
1746   is_format_depth_or_depthstencil =
1747      _mesa_is_depth_format(format) ||
1748      _mesa_is_depthstencil_format(format);
1749
1750   colorFormat = _mesa_is_color_format(format);
1751
1752   if (_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat)
1753      return false;
1754
1755   if (is_internalFormat_depth_or_depthstencil !=
1756       is_format_depth_or_depthstencil)
1757      return false;
1758
1759   if (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format))
1760      return false;
1761
1762   return true;
1763}
1764
1765/**
1766 * Test the combination of format, type and internal format arguments of
1767 * different texture operations on GLES.
1768 *
1769 * \param ctx GL context.
1770 * \param format pixel data format given by the user.
1771 * \param type pixel data type given by the user.
1772 * \param internalFormat internal format given by the user.
1773 * \param callerName name of the caller function to print in the error message
1774 *
1775 * \return true if a error is found, false otherwise
1776 *
1777 * Currently, it is used by texture_error_check() and texsubimage_error_check().
1778 */
1779static bool
1780texture_format_error_check_gles(struct gl_context *ctx, GLenum format,
1781                                GLenum type, GLenum internalFormat, const char *callerName)
1782{
1783   GLenum err = _mesa_gles_error_check_format_and_type(ctx, format, type,
1784                                                       internalFormat);
1785   if (err != GL_NO_ERROR) {
1786      _mesa_error(ctx, err,
1787                  "%s(format = %s, type = %s, internalformat = %s)",
1788                  callerName, _mesa_enum_to_string(format),
1789                  _mesa_enum_to_string(type),
1790                  _mesa_enum_to_string(internalFormat));
1791      return true;
1792   }
1793
1794   return false;
1795}
1796
1797/**
1798 * Test the glTexImage[123]D() parameters for errors.
1799 *
1800 * \param ctx GL context.
1801 * \param dimensions texture image dimensions (must be 1, 2 or 3).
1802 * \param target texture target given by the user (already validated).
1803 * \param level image level given by the user.
1804 * \param internalFormat internal format given by the user.
1805 * \param format pixel data format given by the user.
1806 * \param type pixel data type given by the user.
1807 * \param width image width given by the user.
1808 * \param height image height given by the user.
1809 * \param depth image depth given by the user.
1810 * \param border image border given by the user.
1811 *
1812 * \return GL_TRUE if a error is found, GL_FALSE otherwise
1813 *
1814 * Verifies each of the parameters against the constants specified in
1815 * __struct gl_contextRec::Const and the supported extensions, and according
1816 * to the OpenGL specification.
1817 * Note that we don't fully error-check the width, height, depth values
1818 * here.  That's done in _mesa_legal_texture_dimensions() which is used
1819 * by several other GL entrypoints.  Plus, texture dims have a special
1820 * interaction with proxy textures.
1821 */
1822static GLboolean
1823texture_error_check( struct gl_context *ctx,
1824                     GLuint dimensions, GLenum target,
1825                     struct gl_texture_object* texObj,
1826                     GLint level, GLint internalFormat,
1827                     GLenum format, GLenum type,
1828                     GLint width, GLint height,
1829                     GLint depth, GLint border,
1830                     const GLvoid *pixels )
1831{
1832   GLenum err;
1833
1834   /* Note: for proxy textures, some error conditions immediately generate
1835    * a GL error in the usual way.  But others do not generate a GL error.
1836    * Instead, they cause the width, height, depth, format fields of the
1837    * texture image to be zeroed-out.  The GL spec seems to indicate that the
1838    * zero-out behaviour is only used in cases related to memory allocation.
1839    */
1840
1841   /* level check */
1842   if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
1843      _mesa_error(ctx, GL_INVALID_VALUE,
1844                  "glTexImage%dD(level=%d)", dimensions, level);
1845      return GL_TRUE;
1846   }
1847
1848   /* Check border */
1849   if (border < 0 || border > 1 ||
1850       ((ctx->API != API_OPENGL_COMPAT ||
1851         target == GL_TEXTURE_RECTANGLE_NV ||
1852         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
1853      _mesa_error(ctx, GL_INVALID_VALUE,
1854                  "glTexImage%dD(border=%d)", dimensions, border);
1855      return GL_TRUE;
1856   }
1857
1858   if (width < 0 || height < 0 || depth < 0) {
1859      _mesa_error(ctx, GL_INVALID_VALUE,
1860                  "glTexImage%dD(width, height or depth < 0)", dimensions);
1861      return GL_TRUE;
1862   }
1863
1864   /* Check incoming image format and type */
1865   err = _mesa_error_check_format_and_type(ctx, format, type);
1866   if (err != GL_NO_ERROR) {
1867      /* Prior to OpenGL-ES 2.0, an INVALID_VALUE is expected instead of
1868       * INVALID_ENUM. From page 73 OpenGL ES 1.1 spec:
1869       *
1870       *     "Specifying a value for internalformat that is not one of the
1871       *      above (acceptable) values generates the error INVALID VALUE."
1872       */
1873      if (err == GL_INVALID_ENUM && _mesa_is_gles(ctx) && ctx->Version < 20)
1874         err = GL_INVALID_VALUE;
1875
1876      _mesa_error(ctx, err,
1877                  "glTexImage%dD(incompatible format = %s, type = %s)",
1878                  dimensions, _mesa_enum_to_string(format),
1879                  _mesa_enum_to_string(type));
1880      return GL_TRUE;
1881   }
1882
1883   /* Check internalFormat */
1884   if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
1885      _mesa_error(ctx, GL_INVALID_VALUE,
1886                  "glTexImage%dD(internalFormat=%s)",
1887                  dimensions, _mesa_enum_to_string(internalFormat));
1888      return GL_TRUE;
1889   }
1890
1891   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
1892    * combinations of format, internalFormat, and type that can be used.
1893    * Formats and types that require additional extensions (e.g., GL_FLOAT
1894    * requires GL_OES_texture_float) are filtered elsewhere.
1895    */
1896   char bufCallerName[20];
1897   snprintf(bufCallerName, 20, "glTexImage%dD", dimensions);
1898   if (_mesa_is_gles(ctx) &&
1899       texture_format_error_check_gles(ctx, format, type,
1900                                       internalFormat, bufCallerName)) {
1901      return GL_TRUE;
1902   }
1903
1904   /* validate the bound PBO, if any */
1905   if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack,
1906                                  width, height, depth, format, type,
1907                                  INT_MAX, pixels, "glTexImage")) {
1908      return GL_TRUE;
1909   }
1910
1911   /* make sure internal format and format basically agree */
1912   if (!texture_formats_agree(internalFormat, format)) {
1913      _mesa_error(ctx, GL_INVALID_OPERATION,
1914                  "glTexImage%dD(incompatible internalFormat = %s, format = %s)",
1915                  dimensions, _mesa_enum_to_string(internalFormat),
1916                  _mesa_enum_to_string(format));
1917      return GL_TRUE;
1918   }
1919
1920   /* additional checks for ycbcr textures */
1921   if (internalFormat == GL_YCBCR_MESA) {
1922      assert(ctx->Extensions.MESA_ycbcr_texture);
1923      if (type != GL_UNSIGNED_SHORT_8_8_MESA &&
1924          type != GL_UNSIGNED_SHORT_8_8_REV_MESA) {
1925         char message[100];
1926         snprintf(message, sizeof(message),
1927                        "glTexImage%dD(format/type YCBCR mismatch)",
1928                        dimensions);
1929         _mesa_error(ctx, GL_INVALID_ENUM, "%s", message);
1930         return GL_TRUE; /* error */
1931      }
1932      if (target != GL_TEXTURE_2D &&
1933          target != GL_PROXY_TEXTURE_2D &&
1934          target != GL_TEXTURE_RECTANGLE_NV &&
1935          target != GL_PROXY_TEXTURE_RECTANGLE_NV) {
1936         _mesa_error(ctx, GL_INVALID_ENUM,
1937                     "glTexImage%dD(bad target for YCbCr texture)",
1938                     dimensions);
1939         return GL_TRUE;
1940      }
1941      if (border != 0) {
1942         char message[100];
1943         snprintf(message, sizeof(message),
1944                        "glTexImage%dD(format=GL_YCBCR_MESA and border=%d)",
1945                        dimensions, border);
1946         _mesa_error(ctx, GL_INVALID_VALUE, "%s", message);
1947         return GL_TRUE;
1948      }
1949   }
1950
1951   /* additional checks for depth textures */
1952   if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalFormat)) {
1953      _mesa_error(ctx, GL_INVALID_OPERATION,
1954                  "glTexImage%dD(bad target for texture)", dimensions);
1955      return GL_TRUE;
1956   }
1957
1958   /* additional checks for compressed textures */
1959   if (_mesa_is_compressed_format(ctx, internalFormat)) {
1960      GLenum err;
1961      if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) {
1962         _mesa_error(ctx, err,
1963                     "glTexImage%dD(target can't be compressed)", dimensions);
1964         return GL_TRUE;
1965      }
1966      if (_mesa_format_no_online_compression(internalFormat)) {
1967         _mesa_error(ctx, GL_INVALID_OPERATION,
1968                     "glTexImage%dD(no compression for format)", dimensions);
1969         return GL_TRUE;
1970      }
1971      if (border != 0) {
1972         _mesa_error(ctx, GL_INVALID_OPERATION,
1973                     "glTexImage%dD(border!=0)", dimensions);
1974         return GL_TRUE;
1975      }
1976   }
1977
1978   /* additional checks for integer textures */
1979   if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) &&
1980       (_mesa_is_enum_format_integer(format) !=
1981        _mesa_is_enum_format_integer(internalFormat))) {
1982      _mesa_error(ctx, GL_INVALID_OPERATION,
1983                  "glTexImage%dD(integer/non-integer format mismatch)",
1984                  dimensions);
1985      return GL_TRUE;
1986   }
1987
1988   if (!mutable_tex_object(texObj)) {
1989      _mesa_error(ctx, GL_INVALID_OPERATION,
1990                  "glTexImage%dD(immutable texture)", dimensions);
1991      return GL_TRUE;
1992   }
1993
1994   /* if we get here, the parameters are OK */
1995   return GL_FALSE;
1996}
1997
1998
1999/**
2000 * Error checking for glCompressedTexImage[123]D().
2001 * Note that the width, height and depth values are not fully error checked
2002 * here.
2003 * \return GL_TRUE if a error is found, GL_FALSE otherwise
2004 */
2005static GLenum
2006compressed_texture_error_check(struct gl_context *ctx, GLint dimensions,
2007                               GLenum target, struct gl_texture_object* texObj,
2008                               GLint level, GLenum internalFormat, GLsizei width,
2009                               GLsizei height, GLsizei depth, GLint border,
2010                               GLsizei imageSize, const GLvoid *data)
2011{
2012   const GLint maxLevels = _mesa_max_texture_levels(ctx, target);
2013   GLint expectedSize;
2014   GLenum error = GL_NO_ERROR;
2015   char *reason = ""; /* no error */
2016
2017   if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &error)) {
2018      reason = "target";
2019      goto error;
2020   }
2021
2022   /* This will detect any invalid internalFormat value */
2023   if (!_mesa_is_compressed_format(ctx, internalFormat)) {
2024      _mesa_error(ctx, GL_INVALID_ENUM,
2025                  "glCompressedTexImage%dD(internalFormat=%s)",
2026                  dimensions, _mesa_enum_to_string(internalFormat));
2027      return GL_TRUE;
2028   }
2029
2030   /* validate the bound PBO, if any */
2031   if (!_mesa_validate_pbo_source_compressed(ctx, dimensions, &ctx->Unpack,
2032                                             imageSize, data,
2033                                             "glCompressedTexImage")) {
2034      return GL_TRUE;
2035   }
2036
2037   switch (internalFormat) {
2038   case GL_PALETTE4_RGB8_OES:
2039   case GL_PALETTE4_RGBA8_OES:
2040   case GL_PALETTE4_R5_G6_B5_OES:
2041   case GL_PALETTE4_RGBA4_OES:
2042   case GL_PALETTE4_RGB5_A1_OES:
2043   case GL_PALETTE8_RGB8_OES:
2044   case GL_PALETTE8_RGBA8_OES:
2045   case GL_PALETTE8_R5_G6_B5_OES:
2046   case GL_PALETTE8_RGBA4_OES:
2047   case GL_PALETTE8_RGB5_A1_OES:
2048      /* check level (note that level should be zero or less!) */
2049      if (level > 0 || level < -maxLevels) {
2050         reason = "level";
2051         error = GL_INVALID_VALUE;
2052         goto error;
2053      }
2054
2055      if (dimensions != 2) {
2056         reason = "compressed paletted textures must be 2D";
2057         error = GL_INVALID_OPERATION;
2058         goto error;
2059      }
2060
2061      /* Figure out the expected texture size (in bytes).  This will be
2062       * checked against the actual size later.
2063       */
2064      expectedSize = _mesa_cpal_compressed_size(level, internalFormat,
2065                                                width, height);
2066
2067      /* This is for the benefit of the TestProxyTexImage below.  It expects
2068       * level to be non-negative.  OES_compressed_paletted_texture uses a
2069       * weird mechanism where the level specified to glCompressedTexImage2D
2070       * is -(n-1) number of levels in the texture, and the data specifies the
2071       * complete mipmap stack.  This is done to ensure the palette is the
2072       * same for all levels.
2073       */
2074      level = -level;
2075      break;
2076
2077   default:
2078      /* check level */
2079      if (level < 0 || level >= maxLevels) {
2080         reason = "level";
2081         error = GL_INVALID_VALUE;
2082         goto error;
2083      }
2084
2085      /* Figure out the expected texture size (in bytes).  This will be
2086       * checked against the actual size later.
2087       */
2088      expectedSize = compressed_tex_size(width, height, depth, internalFormat);
2089      break;
2090   }
2091
2092   /* This should really never fail */
2093   if (_mesa_base_tex_format(ctx, internalFormat) < 0) {
2094      reason = "internalFormat";
2095      error = GL_INVALID_ENUM;
2096      goto error;
2097   }
2098
2099   /* No compressed formats support borders at this time */
2100   if (border != 0) {
2101      reason = "border != 0";
2102      error = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_VALUE;
2103      goto error;
2104   }
2105
2106   /* Check for invalid pixel storage modes */
2107   if (!_mesa_compressed_pixel_storage_error_check(ctx, dimensions,
2108                                                   &ctx->Unpack,
2109                                                   "glCompressedTexImage")) {
2110      return GL_FALSE;
2111   }
2112
2113   /* check image size in bytes */
2114   if (expectedSize != imageSize) {
2115      /* Per GL_ARB_texture_compression:  GL_INVALID_VALUE is generated [...]
2116       * if <imageSize> is not consistent with the format, dimensions, and
2117       * contents of the specified image.
2118       */
2119      reason = "imageSize inconsistent with width/height/format";
2120      error = GL_INVALID_VALUE;
2121      goto error;
2122   }
2123
2124   if (!mutable_tex_object(texObj)) {
2125      reason = "immutable texture";
2126      error = GL_INVALID_OPERATION;
2127      goto error;
2128   }
2129
2130   return GL_FALSE;
2131
2132error:
2133   /* Note: not all error paths exit through here. */
2134   _mesa_error(ctx, error, "glCompressedTexImage%dD(%s)",
2135               dimensions, reason);
2136   return GL_TRUE;
2137}
2138
2139
2140
2141/**
2142 * Test glTexSubImage[123]D() parameters for errors.
2143 *
2144 * \param ctx GL context.
2145 * \param dimensions texture image dimensions (must be 1, 2 or 3).
2146 * \param target texture target given by the user (already validated)
2147 * \param level image level given by the user.
2148 * \param xoffset sub-image x offset given by the user.
2149 * \param yoffset sub-image y offset given by the user.
2150 * \param zoffset sub-image z offset given by the user.
2151 * \param format pixel data format given by the user.
2152 * \param type pixel data type given by the user.
2153 * \param width image width given by the user.
2154 * \param height image height given by the user.
2155 * \param depth image depth given by the user.
2156 *
2157 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2158 *
2159 * Verifies each of the parameters against the constants specified in
2160 * __struct gl_contextRec::Const and the supported extensions, and according
2161 * to the OpenGL specification.
2162 */
2163static GLboolean
2164texsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
2165                        struct gl_texture_object *texObj,
2166                        GLenum target, GLint level,
2167                        GLint xoffset, GLint yoffset, GLint zoffset,
2168                        GLint width, GLint height, GLint depth,
2169                        GLenum format, GLenum type, const GLvoid *pixels,
2170                        const char *callerName)
2171{
2172   struct gl_texture_image *texImage;
2173   GLenum err;
2174
2175   if (!texObj) {
2176      /* must be out of memory */
2177      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", callerName);
2178      return GL_TRUE;
2179   }
2180
2181   /* level check */
2182   if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
2183      _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level);
2184      return GL_TRUE;
2185   }
2186
2187   if (error_check_subtexture_negative_dimensions(ctx, dimensions,
2188                                                  width, height, depth,
2189                                                  callerName)) {
2190      return GL_TRUE;
2191   }
2192
2193   texImage = _mesa_select_tex_image(texObj, target, level);
2194   if (!texImage) {
2195      /* non-existant texture level */
2196      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)",
2197                  callerName, level);
2198      return GL_TRUE;
2199   }
2200
2201   err = _mesa_error_check_format_and_type(ctx, format, type);
2202   if (err != GL_NO_ERROR) {
2203      _mesa_error(ctx, err,
2204                  "%s(incompatible format = %s, type = %s)",
2205                  callerName, _mesa_enum_to_string(format),
2206                  _mesa_enum_to_string(type));
2207      return GL_TRUE;
2208   }
2209
2210   if (!texture_formats_agree(texImage->InternalFormat, format)) {
2211      _mesa_error(ctx, GL_INVALID_OPERATION,
2212                  "%s(incompatible internalFormat = %s, format = %s)",
2213                  callerName,
2214                  _mesa_enum_to_string(texImage->InternalFormat),
2215                  _mesa_enum_to_string(format));
2216      return GL_TRUE;
2217   }
2218
2219   GLenum internalFormat = _mesa_is_gles(ctx) ?
2220      oes_float_internal_format(ctx, texImage->InternalFormat, type) :
2221      texImage->InternalFormat;
2222
2223   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
2224    * combinations of format, internalFormat, and type that can be used.
2225    * Formats and types that require additional extensions (e.g., GL_FLOAT
2226    * requires GL_OES_texture_float) are filtered elsewhere.
2227    */
2228   if (_mesa_is_gles(ctx) &&
2229       texture_format_error_check_gles(ctx, format, type,
2230                                       internalFormat, callerName)) {
2231      return GL_TRUE;
2232   }
2233
2234   /* validate the bound PBO, if any */
2235   if (!_mesa_validate_pbo_source(ctx, dimensions, &ctx->Unpack,
2236                                  width, height, depth, format, type,
2237                                  INT_MAX, pixels, callerName)) {
2238      return GL_TRUE;
2239   }
2240
2241   if (error_check_subtexture_dimensions(ctx, dimensions,
2242                                         texImage, xoffset, yoffset, zoffset,
2243                                         width, height, depth, callerName)) {
2244      return GL_TRUE;
2245   }
2246
2247   if (_mesa_is_format_compressed(texImage->TexFormat)) {
2248      if (_mesa_format_no_online_compression(texImage->InternalFormat)) {
2249         _mesa_error(ctx, GL_INVALID_OPERATION,
2250               "%s(no compression for format)", callerName);
2251         return GL_TRUE;
2252      }
2253   }
2254
2255   if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
2256      /* both source and dest must be integer-valued, or neither */
2257      if (_mesa_is_format_integer_color(texImage->TexFormat) !=
2258          _mesa_is_enum_format_integer(format)) {
2259         _mesa_error(ctx, GL_INVALID_OPERATION,
2260                     "%s(integer/non-integer format mismatch)", callerName);
2261         return GL_TRUE;
2262      }
2263   }
2264
2265   return GL_FALSE;
2266}
2267
2268
2269/**
2270 * Test glCopyTexImage[12]D() parameters for errors.
2271 *
2272 * \param ctx GL context.
2273 * \param dimensions texture image dimensions (must be 1, 2 or 3).
2274 * \param target texture target given by the user.
2275 * \param level image level given by the user.
2276 * \param internalFormat internal format given by the user.
2277 * \param width image width given by the user.
2278 * \param height image height given by the user.
2279 * \param border texture border.
2280 *
2281 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2282 *
2283 * Verifies each of the parameters against the constants specified in
2284 * __struct gl_contextRec::Const and the supported extensions, and according
2285 * to the OpenGL specification.
2286 */
2287static GLboolean
2288copytexture_error_check( struct gl_context *ctx, GLuint dimensions,
2289                         GLenum target, struct gl_texture_object* texObj,
2290                         GLint level, GLint internalFormat, GLint border )
2291{
2292   GLint baseFormat;
2293   GLint rb_base_format;
2294   struct gl_renderbuffer *rb;
2295   GLenum rb_internal_format;
2296
2297   /* level check */
2298   if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
2299      _mesa_error(ctx, GL_INVALID_VALUE,
2300                  "glCopyTexImage%dD(level=%d)", dimensions, level);
2301      return GL_TRUE;
2302   }
2303
2304   /* Check that the source buffer is complete */
2305   if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
2306      if (ctx->ReadBuffer->_Status == 0) {
2307         _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2308      }
2309      if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2310         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2311                     "glCopyTexImage%dD(invalid readbuffer)", dimensions);
2312         return GL_TRUE;
2313      }
2314
2315      if (ctx->ReadBuffer->Visual.samples > 0) {
2316         _mesa_error(ctx, GL_INVALID_OPERATION,
2317                     "glCopyTexImage%dD(multisample FBO)", dimensions);
2318         return GL_TRUE;
2319      }
2320   }
2321
2322   /* Check border */
2323   if (border < 0 || border > 1 ||
2324       ((ctx->API != API_OPENGL_COMPAT ||
2325         target == GL_TEXTURE_RECTANGLE_NV ||
2326         target == GL_PROXY_TEXTURE_RECTANGLE_NV) && border != 0)) {
2327      _mesa_error(ctx, GL_INVALID_VALUE,
2328                  "glCopyTexImage%dD(border=%d)", dimensions, border);
2329      return GL_TRUE;
2330   }
2331
2332   /* OpenGL ES 1.x and OpenGL ES 2.0 impose additional restrictions on the
2333    * internalFormat.
2334    */
2335   if (_mesa_is_gles(ctx) && !_mesa_is_gles3(ctx)) {
2336      switch (internalFormat) {
2337      case GL_ALPHA:
2338      case GL_RGB:
2339      case GL_RGBA:
2340      case GL_LUMINANCE:
2341      case GL_LUMINANCE_ALPHA:
2342
2343      /* Added by GL_OES_required_internalformat (always enabled) in table 3.4.y.*/
2344      case GL_ALPHA8:
2345      case GL_LUMINANCE8:
2346      case GL_LUMINANCE8_ALPHA8:
2347      case GL_LUMINANCE4_ALPHA4:
2348      case GL_RGB565:
2349      case GL_RGB8:
2350      case GL_RGBA4:
2351      case GL_RGB5_A1:
2352      case GL_RGBA8:
2353      case GL_DEPTH_COMPONENT16:
2354      case GL_DEPTH_COMPONENT24:
2355      case GL_DEPTH_COMPONENT32:
2356      case GL_DEPTH24_STENCIL8:
2357      case GL_RGB10:
2358      case GL_RGB10_A2:
2359         break;
2360
2361      default:
2362         _mesa_error(ctx, GL_INVALID_ENUM,
2363                     "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2364                     _mesa_enum_to_string(internalFormat));
2365         return GL_TRUE;
2366      }
2367   } else {
2368      /*
2369       * Section 8.6 (Alternate Texture Image Specification Commands) of the
2370       * OpenGL 4.5 (Compatibility Profile) spec says:
2371       *
2372       *     "Parameters level, internalformat, and border are specified using
2373       *     the same values, with the same meanings, as the corresponding
2374       *     arguments of TexImage2D, except that internalformat may not be
2375       *     specified as 1, 2, 3, or 4."
2376       */
2377      if (internalFormat >= 1 && internalFormat <= 4) {
2378         _mesa_error(ctx, GL_INVALID_ENUM,
2379                     "glCopyTexImage%dD(internalFormat=%d)", dimensions,
2380                     internalFormat);
2381         return GL_TRUE;
2382      }
2383   }
2384
2385   baseFormat = _mesa_base_tex_format(ctx, internalFormat);
2386   if (baseFormat < 0) {
2387      _mesa_error(ctx, GL_INVALID_ENUM,
2388                  "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2389                  _mesa_enum_to_string(internalFormat));
2390      return GL_TRUE;
2391   }
2392
2393   rb = _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
2394   if (rb == NULL) {
2395      _mesa_error(ctx, GL_INVALID_OPERATION,
2396                  "glCopyTexImage%dD(read buffer)", dimensions);
2397      return GL_TRUE;
2398   }
2399
2400   rb_internal_format = rb->InternalFormat;
2401   rb_base_format = _mesa_base_tex_format(ctx, rb->InternalFormat);
2402   if (_mesa_is_color_format(internalFormat)) {
2403      if (rb_base_format < 0) {
2404         _mesa_error(ctx, GL_INVALID_VALUE,
2405                     "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2406                     _mesa_enum_to_string(internalFormat));
2407         return GL_TRUE;
2408      }
2409   }
2410
2411   if (_mesa_is_gles(ctx)) {
2412      bool valid = true;
2413      if (_mesa_components_in_format(baseFormat) >
2414          _mesa_components_in_format(rb_base_format)) {
2415         valid = false;
2416      }
2417      if (baseFormat == GL_DEPTH_COMPONENT ||
2418          baseFormat == GL_DEPTH_STENCIL ||
2419          baseFormat == GL_STENCIL_INDEX ||
2420          rb_base_format == GL_DEPTH_COMPONENT ||
2421          rb_base_format == GL_DEPTH_STENCIL ||
2422          rb_base_format == GL_STENCIL_INDEX ||
2423          ((baseFormat == GL_LUMINANCE_ALPHA ||
2424            baseFormat == GL_ALPHA) &&
2425           rb_base_format != GL_RGBA) ||
2426          internalFormat == GL_RGB9_E5) {
2427         valid = false;
2428      }
2429      if (internalFormat == GL_RGB9_E5) {
2430         valid = false;
2431      }
2432      if (!valid) {
2433         _mesa_error(ctx, GL_INVALID_OPERATION,
2434                     "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2435                     _mesa_enum_to_string(internalFormat));
2436         return GL_TRUE;
2437      }
2438   }
2439
2440   if (_mesa_is_gles3(ctx)) {
2441      bool rb_is_srgb = (ctx->Extensions.EXT_sRGB &&
2442                         _mesa_is_format_srgb(rb->Format));
2443      bool dst_is_srgb = false;
2444
2445      if (_mesa_get_linear_internalformat(internalFormat) != internalFormat) {
2446         dst_is_srgb = true;
2447      }
2448
2449      if (rb_is_srgb != dst_is_srgb) {
2450         /* Page 137 (page 149 of the PDF) in section 3.8.5 of the
2451          * OpenGLES 3.0.0 spec says:
2452          *
2453          *     "The error INVALID_OPERATION is also generated if the
2454          *     value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING for the
2455          *     framebuffer attachment corresponding to the read buffer
2456          *     is LINEAR (see section 6.1.13) and internalformat is
2457          *     one of the sRGB formats described in section 3.8.16, or
2458          *     if the value of FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING is
2459          *     SRGB and internalformat is not one of the sRGB formats."
2460          */
2461         _mesa_error(ctx, GL_INVALID_OPERATION,
2462                     "glCopyTexImage%dD(srgb usage mismatch)", dimensions);
2463         return GL_TRUE;
2464      }
2465
2466      /* Page 139, Table 3.15 of OpenGL ES 3.0 spec does not define ReadPixels
2467       * types for SNORM formats. Also, conversion to SNORM formats is not
2468       * allowed by Table 3.2 on Page 110.
2469       */
2470      if (!_mesa_has_EXT_render_snorm(ctx) &&
2471          _mesa_is_enum_format_snorm(internalFormat)) {
2472         _mesa_error(ctx, GL_INVALID_OPERATION,
2473                     "glCopyTexImage%dD(internalFormat=%s)", dimensions,
2474                     _mesa_enum_to_string(internalFormat));
2475         return GL_TRUE;
2476      }
2477   }
2478
2479   if (!_mesa_source_buffer_exists(ctx, baseFormat)) {
2480      _mesa_error(ctx, GL_INVALID_OPERATION,
2481                  "glCopyTexImage%dD(missing readbuffer)", dimensions);
2482      return GL_TRUE;
2483   }
2484
2485   /* From the EXT_texture_integer spec:
2486    *
2487    *     "INVALID_OPERATION is generated by CopyTexImage* and CopyTexSubImage*
2488    *      if the texture internalformat is an integer format and the read color
2489    *      buffer is not an integer format, or if the internalformat is not an
2490    *      integer format and the read color buffer is an integer format."
2491    */
2492   if (_mesa_is_color_format(internalFormat)) {
2493      bool is_int = _mesa_is_enum_format_integer(internalFormat);
2494      bool is_rbint = _mesa_is_enum_format_integer(rb_internal_format);
2495      bool is_unorm = _mesa_is_enum_format_unorm(internalFormat);
2496      bool is_rbunorm = _mesa_is_enum_format_unorm(rb_internal_format);
2497      if (is_int || is_rbint) {
2498         if (is_int != is_rbint) {
2499            _mesa_error(ctx, GL_INVALID_OPERATION,
2500                        "glCopyTexImage%dD(integer vs non-integer)", dimensions);
2501            return GL_TRUE;
2502         } else if (_mesa_is_gles(ctx) &&
2503                    _mesa_is_enum_format_unsigned_int(internalFormat) !=
2504                      _mesa_is_enum_format_unsigned_int(rb_internal_format)) {
2505            _mesa_error(ctx, GL_INVALID_OPERATION,
2506                        "glCopyTexImage%dD(signed vs unsigned integer)",
2507                        dimensions);
2508            return GL_TRUE;
2509         }
2510      }
2511
2512      /* From page 138 of OpenGL ES 3.0 spec:
2513       *    "The error INVALID_OPERATION is generated if floating-point RGBA
2514       *    data is required; if signed integer RGBA data is required and the
2515       *    format of the current color buffer is not signed integer; if
2516       *    unsigned integer RGBA data is required and the format of the
2517       *    current color buffer is not unsigned integer; or if fixed-point
2518       *    RGBA data is required and the format of the current color buffer
2519       *    is not fixed-point.
2520       */
2521      if (_mesa_is_gles(ctx) && is_unorm != is_rbunorm)
2522            _mesa_error(ctx, GL_INVALID_OPERATION,
2523                        "glCopyTexImage%dD(unorm vs non-unorm)", dimensions);
2524   }
2525
2526   if (_mesa_is_compressed_format(ctx, internalFormat)) {
2527      GLenum err;
2528      if (!_mesa_target_can_be_compressed(ctx, target, internalFormat, &err)) {
2529         _mesa_error(ctx, err,
2530                     "glCopyTexImage%dD(target can't be compressed)", dimensions);
2531         return GL_TRUE;
2532      }
2533      if (_mesa_format_no_online_compression(internalFormat)) {
2534         _mesa_error(ctx, GL_INVALID_OPERATION,
2535               "glCopyTexImage%dD(no compression for format)", dimensions);
2536         return GL_TRUE;
2537      }
2538      if (border != 0) {
2539         _mesa_error(ctx, GL_INVALID_OPERATION,
2540                     "glCopyTexImage%dD(border!=0)", dimensions);
2541         return GL_TRUE;
2542      }
2543   }
2544
2545   if (!mutable_tex_object(texObj)) {
2546      _mesa_error(ctx, GL_INVALID_OPERATION,
2547                  "glCopyTexImage%dD(immutable texture)", dimensions);
2548      return GL_TRUE;
2549   }
2550
2551   /* if we get here, the parameters are OK */
2552   return GL_FALSE;
2553}
2554
2555
2556/**
2557 * Test glCopyTexSubImage[12]D() parameters for errors.
2558 * \return GL_TRUE if an error was detected, or GL_FALSE if no errors.
2559 */
2560static GLboolean
2561copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions,
2562                            const struct gl_texture_object *texObj,
2563                            GLenum target, GLint level,
2564                            GLint xoffset, GLint yoffset, GLint zoffset,
2565                            GLint width, GLint height, const char *caller)
2566{
2567   assert(texObj);
2568
2569   struct gl_texture_image *texImage;
2570
2571   /* Check that the source buffer is complete */
2572   if (_mesa_is_user_fbo(ctx->ReadBuffer)) {
2573      if (ctx->ReadBuffer->_Status == 0) {
2574         _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
2575      }
2576      if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
2577         _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
2578                     "%s(invalid readbuffer)", caller);
2579         return GL_TRUE;
2580      }
2581
2582      if (ctx->ReadBuffer->Visual.samples > 0) {
2583         _mesa_error(ctx, GL_INVALID_OPERATION,
2584                "%s(multisample FBO)", caller);
2585         return GL_TRUE;
2586      }
2587   }
2588
2589   /* Check level */
2590   if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
2591      _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", caller, level);
2592      return GL_TRUE;
2593   }
2594
2595   texImage = _mesa_select_tex_image(texObj, target, level);
2596   if (!texImage) {
2597      /* destination image does not exist */
2598      _mesa_error(ctx, GL_INVALID_OPERATION,
2599                  "%s(invalid texture level %d)", caller, level);
2600      return GL_TRUE;
2601   }
2602
2603   if (error_check_subtexture_negative_dimensions(ctx, dimensions,
2604                                                  width, height, 1, caller)) {
2605      return GL_TRUE;
2606   }
2607
2608   if (error_check_subtexture_dimensions(ctx, dimensions, texImage,
2609                                         xoffset, yoffset, zoffset,
2610                                         width, height, 1, caller)) {
2611      return GL_TRUE;
2612   }
2613
2614   if (_mesa_is_format_compressed(texImage->TexFormat)) {
2615      if (_mesa_format_no_online_compression(texImage->InternalFormat)) {
2616         _mesa_error(ctx, GL_INVALID_OPERATION,
2617               "%s(no compression for format)", caller);
2618         return GL_TRUE;
2619      }
2620   }
2621
2622   if (texImage->InternalFormat == GL_YCBCR_MESA) {
2623      _mesa_error(ctx, GL_INVALID_OPERATION, "%s()", caller);
2624      return GL_TRUE;
2625   }
2626
2627   /* From OpenGL ES 3.2 spec, section 8.6:
2628    *
2629    *     "An INVALID_OPERATION error is generated by CopyTexSubImage3D,
2630    *      CopyTexImage2D, or CopyTexSubImage2D if the internalformat of the
2631    *      texture image being (re)specified is RGB9_E5"
2632    */
2633   if (texImage->InternalFormat == GL_RGB9_E5 &&
2634       !_mesa_is_desktop_gl(ctx)) {
2635      _mesa_error(ctx, GL_INVALID_OPERATION,
2636                  "%s(invalid internal format %s)", caller,
2637                  _mesa_enum_to_string(texImage->InternalFormat));
2638      return GL_TRUE;
2639   }
2640
2641   if (!_mesa_source_buffer_exists(ctx, texImage->_BaseFormat)) {
2642      _mesa_error(ctx, GL_INVALID_OPERATION,
2643                  "%s(missing readbuffer, format=%s)", caller,
2644                  _mesa_enum_to_string(texImage->_BaseFormat));
2645      return GL_TRUE;
2646   }
2647
2648   /* From the EXT_texture_integer spec:
2649    *
2650    *     "INVALID_OPERATION is generated by CopyTexImage* and
2651    *     CopyTexSubImage* if the texture internalformat is an integer format
2652    *     and the read color buffer is not an integer format, or if the
2653    *     internalformat is not an integer format and the read color buffer
2654    *     is an integer format."
2655    */
2656   if (_mesa_is_color_format(texImage->InternalFormat)) {
2657      struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
2658
2659      if (_mesa_is_format_integer_color(rb->Format) !=
2660          _mesa_is_format_integer_color(texImage->TexFormat)) {
2661         _mesa_error(ctx, GL_INVALID_OPERATION,
2662                     "%s(integer vs non-integer)", caller);
2663         return GL_TRUE;
2664      }
2665   }
2666
2667   /* In the ES 3.2 specification's Table 8.13 (Valid CopyTexImage source
2668    * framebuffer/destination texture base internal format combinations),
2669    * all the entries for stencil are left blank (unsupported).
2670    */
2671   if (_mesa_is_gles(ctx) && _mesa_is_stencil_format(texImage->_BaseFormat)) {
2672      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(stencil disallowed)", caller);
2673      return GL_TRUE;
2674   }
2675
2676   /* if we get here, the parameters are OK */
2677   return GL_FALSE;
2678}
2679
2680
2681/** Callback info for walking over FBO hash table */
2682struct cb_info
2683{
2684   struct gl_context *ctx;
2685   struct gl_texture_object *texObj;
2686   GLuint level, face;
2687};
2688
2689
2690/**
2691 * Check render to texture callback.  Called from _mesa_HashWalk().
2692 */
2693static void
2694check_rtt_cb(void *data, void *userData)
2695{
2696   struct gl_framebuffer *fb = (struct gl_framebuffer *) data;
2697   const struct cb_info *info = (struct cb_info *) userData;
2698   struct gl_context *ctx = info->ctx;
2699   const struct gl_texture_object *texObj = info->texObj;
2700   const GLuint level = info->level, face = info->face;
2701
2702   /* If this is a user-created FBO */
2703   if (_mesa_is_user_fbo(fb)) {
2704      GLuint i;
2705      /* check if any of the FBO's attachments point to 'texObj' */
2706      for (i = 0; i < BUFFER_COUNT; i++) {
2707         struct gl_renderbuffer_attachment *att = fb->Attachment + i;
2708         if (att->Type == GL_TEXTURE &&
2709             att->Texture == texObj &&
2710             att->TextureLevel == level &&
2711             att->CubeMapFace == face) {
2712            _mesa_update_texture_renderbuffer(ctx, fb, att);
2713            assert(att->Renderbuffer->TexImage);
2714            /* Mark fb status as indeterminate to force re-validation */
2715            fb->_Status = 0;
2716
2717            /* Make sure that the revalidation actually happens if this is
2718             * being done to currently-bound buffers.
2719             */
2720            if (fb == ctx->DrawBuffer || fb == ctx->ReadBuffer)
2721               ctx->NewState |= _NEW_BUFFERS;
2722         }
2723      }
2724   }
2725}
2726
2727
2728/**
2729 * When a texture image is specified we have to check if it's bound to
2730 * any framebuffer objects (render to texture) in order to detect changes
2731 * in size or format since that effects FBO completeness.
2732 * Any FBOs rendering into the texture must be re-validated.
2733 */
2734void
2735_mesa_update_fbo_texture(struct gl_context *ctx,
2736                         struct gl_texture_object *texObj,
2737                         GLuint face, GLuint level)
2738{
2739   /* Only check this texture if it's been marked as RenderToTexture */
2740   if (texObj->_RenderToTexture) {
2741      struct cb_info info;
2742      info.ctx = ctx;
2743      info.texObj = texObj;
2744      info.level = level;
2745      info.face = face;
2746      _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info);
2747   }
2748}
2749
2750
2751/**
2752 * If the texture object's GenerateMipmap flag is set and we've
2753 * changed the texture base level image, regenerate the rest of the
2754 * mipmap levels now.
2755 */
2756static inline void
2757check_gen_mipmap(struct gl_context *ctx, GLenum target,
2758                 struct gl_texture_object *texObj, GLint level)
2759{
2760   if (texObj->Attrib.GenerateMipmap &&
2761       level == texObj->Attrib.BaseLevel &&
2762       level < texObj->Attrib.MaxLevel) {
2763      st_generate_mipmap(ctx, target, texObj);
2764   }
2765}
2766
2767
2768/** Debug helper: override the user-requested internal format */
2769static GLenum
2770override_internal_format(GLenum internalFormat, UNUSED GLint width,
2771                         UNUSED GLint height)
2772{
2773#if 0
2774   if (internalFormat == GL_RGBA16F_ARB ||
2775       internalFormat == GL_RGBA32F_ARB) {
2776      printf("Convert rgba float tex to int %d x %d\n", width, height);
2777      return GL_RGBA;
2778   }
2779   else if (internalFormat == GL_RGB16F_ARB ||
2780            internalFormat == GL_RGB32F_ARB) {
2781      printf("Convert rgb float tex to int %d x %d\n", width, height);
2782      return GL_RGB;
2783   }
2784   else if (internalFormat == GL_LUMINANCE_ALPHA16F_ARB ||
2785            internalFormat == GL_LUMINANCE_ALPHA32F_ARB) {
2786      printf("Convert luminance float tex to int %d x %d\n", width, height);
2787      return GL_LUMINANCE_ALPHA;
2788   }
2789   else if (internalFormat == GL_LUMINANCE16F_ARB ||
2790            internalFormat == GL_LUMINANCE32F_ARB) {
2791      printf("Convert luminance float tex to int %d x %d\n", width, height);
2792      return GL_LUMINANCE;
2793   }
2794   else if (internalFormat == GL_ALPHA16F_ARB ||
2795            internalFormat == GL_ALPHA32F_ARB) {
2796      printf("Convert luminance float tex to int %d x %d\n", width, height);
2797      return GL_ALPHA;
2798   }
2799   /*
2800   else if (internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
2801      internalFormat = GL_RGBA;
2802   }
2803   */
2804   else {
2805      return internalFormat;
2806   }
2807#else
2808   return internalFormat;
2809#endif
2810}
2811
2812
2813/**
2814 * Choose the actual hardware format for a texture image.
2815 * Try to use the same format as the previous image level when possible.
2816 * Otherwise, ask the driver for the best format.
2817 * It's important to try to choose a consistant format for all levels
2818 * for efficient texture memory layout/allocation.  In particular, this
2819 * comes up during automatic mipmap generation.
2820 */
2821mesa_format
2822_mesa_choose_texture_format(struct gl_context *ctx,
2823                            struct gl_texture_object *texObj,
2824                            GLenum target, GLint level,
2825                            GLenum internalFormat, GLenum format, GLenum type)
2826{
2827   mesa_format f = MESA_FORMAT_NONE;
2828
2829   /* see if we've already chosen a format for the previous level */
2830   if (level > 0) {
2831      struct gl_texture_image *prevImage =
2832         _mesa_select_tex_image(texObj, target, level - 1);
2833      /* See if the prev level is defined and has an internal format which
2834       * matches the new internal format.
2835       */
2836      if (prevImage &&
2837          prevImage->Width > 0 &&
2838          prevImage->InternalFormat == internalFormat) {
2839         /* use the same format */
2840         assert(prevImage->TexFormat != MESA_FORMAT_NONE);
2841         return prevImage->TexFormat;
2842      }
2843   }
2844
2845   f = st_ChooseTextureFormat(ctx, target, internalFormat,
2846                              format, type);
2847   assert(f != MESA_FORMAT_NONE);
2848   return f;
2849}
2850
2851
2852/**
2853 * Adjust pixel unpack params and image dimensions to strip off the
2854 * one-pixel texture border.
2855 *
2856 * Gallium and intel don't support texture borders.  They've seldem been used
2857 * and seldom been implemented correctly anyway.
2858 *
2859 * \param unpackNew returns the new pixel unpack parameters
2860 */
2861static void
2862strip_texture_border(GLenum target,
2863                     GLint *width, GLint *height, GLint *depth,
2864                     const struct gl_pixelstore_attrib *unpack,
2865                     struct gl_pixelstore_attrib *unpackNew)
2866{
2867   assert(width);
2868   assert(height);
2869   assert(depth);
2870
2871   *unpackNew = *unpack;
2872
2873   if (unpackNew->RowLength == 0)
2874      unpackNew->RowLength = *width;
2875
2876   if (unpackNew->ImageHeight == 0)
2877      unpackNew->ImageHeight = *height;
2878
2879   assert(*width >= 3);
2880   unpackNew->SkipPixels++;  /* skip the border */
2881   *width = *width - 2;      /* reduce the width by two border pixels */
2882
2883   /* The min height of a texture with a border is 3 */
2884   if (*height >= 3 && target != GL_TEXTURE_1D_ARRAY) {
2885      unpackNew->SkipRows++;  /* skip the border */
2886      *height = *height - 2;  /* reduce the height by two border pixels */
2887   }
2888
2889   if (*depth >= 3 &&
2890       target != GL_TEXTURE_2D_ARRAY &&
2891       target != GL_TEXTURE_CUBE_MAP_ARRAY) {
2892      unpackNew->SkipImages++;  /* skip the border */
2893      *depth = *depth - 2;      /* reduce the depth by two border pixels */
2894   }
2895}
2896
2897static struct gl_texture_object *
2898lookup_texture_ext_dsa(struct gl_context *ctx, GLenum target, GLuint texture,
2899                       const char *caller)
2900{
2901   GLenum boundTarget;
2902   switch (target) {
2903   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2904   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2905   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2906   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2907   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2908   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2909      boundTarget = GL_TEXTURE_CUBE_MAP;
2910      break;
2911   default:
2912      boundTarget = target;
2913      break;
2914   }
2915
2916   int targetIndex = _mesa_tex_target_to_index(ctx, boundTarget);
2917   if (targetIndex < 0) {
2918      _mesa_error(ctx, GL_INVALID_ENUM, "%s(target = %s)", caller,
2919                  _mesa_enum_to_string(target));
2920            return NULL;
2921   }
2922   assert(targetIndex < NUM_TEXTURE_TARGETS);
2923
2924   struct gl_texture_object *texObj;
2925   if (texture == 0) {
2926      /* Use a default texture object */
2927      texObj = ctx->Shared->DefaultTex[targetIndex];
2928      assert(texObj);
2929   } else {
2930      bool isGenName;
2931      texObj = _mesa_lookup_texture(ctx, texture);
2932      isGenName = texObj != NULL;
2933      if (!texObj && ctx->API == API_OPENGL_CORE) {
2934         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller);
2935         return NULL;
2936      }
2937
2938      if (!texObj) {
2939         texObj = _mesa_new_texture_object(ctx, texture, boundTarget);
2940         if (!texObj) {
2941            _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
2942            return NULL;
2943         }
2944
2945         /* insert into hash table */
2946         _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj, isGenName);
2947      }
2948
2949      if (texObj->Target != boundTarget) {
2950         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s != %s)",
2951                     caller, _mesa_enum_to_string(texObj->Target),
2952                     _mesa_enum_to_string(target));
2953         return NULL;
2954      }
2955   }
2956
2957   return texObj;
2958}
2959
2960/**
2961 * Common code to implement all the glTexImage1D/2D/3D functions,
2962 * glCompressedTexImage1D/2D/3D and glTextureImage1D/2D/3DEXT
2963 * \param compressed  only GL_TRUE for glCompressedTexImage1D/2D/3D calls.
2964 * \param format  the user's image format (only used if !compressed)
2965 * \param type  the user's image type (only used if !compressed)
2966 * \param imageSize  only used for glCompressedTexImage1D/2D/3D calls.
2967 */
2968static ALWAYS_INLINE void
2969teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
2970         struct gl_texture_object *texObj,
2971         GLenum target, GLint level, GLint internalFormat,
2972         GLsizei width, GLsizei height, GLsizei depth,
2973         GLint border, GLenum format, GLenum type,
2974         GLsizei imageSize, const GLvoid *pixels, bool no_error)
2975{
2976   const char *func = compressed ? "glCompressedTexImage" : "glTexImage";
2977   struct gl_pixelstore_attrib unpack_no_border;
2978   const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
2979   mesa_format texFormat;
2980   bool dimensionsOK = true, sizeOK = true;
2981
2982   FLUSH_VERTICES(ctx, 0, 0);
2983
2984   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) {
2985      if (compressed)
2986         _mesa_debug(ctx,
2987                     "glCompressedTexImage%uD %s %d %s %d %d %d %d %p\n",
2988                     dims,
2989                     _mesa_enum_to_string(target), level,
2990                     _mesa_enum_to_string(internalFormat),
2991                     width, height, depth, border, pixels);
2992      else
2993         _mesa_debug(ctx,
2994                     "glTexImage%uD %s %d %s %d %d %d %d %s %s %p\n",
2995                     dims,
2996                     _mesa_enum_to_string(target), level,
2997                     _mesa_enum_to_string(internalFormat),
2998                     width, height, depth, border,
2999                     _mesa_enum_to_string(format),
3000                     _mesa_enum_to_string(type), pixels);
3001   }
3002
3003   internalFormat = override_internal_format(internalFormat, width, height);
3004
3005   if (!no_error &&
3006       /* target error checking */
3007       !legal_teximage_target(ctx, dims, target)) {
3008      _mesa_error(ctx, GL_INVALID_ENUM, "%s%uD(target=%s)",
3009                  func, dims, _mesa_enum_to_string(target));
3010      return;
3011   }
3012
3013   if (!texObj)
3014      texObj = _mesa_get_current_tex_object(ctx, target);
3015
3016   if (!no_error) {
3017      /* general error checking */
3018      if (compressed) {
3019         if (compressed_texture_error_check(ctx, dims, target, texObj,
3020                                            level, internalFormat,
3021                                            width, height, depth,
3022                                            border, imageSize, pixels))
3023            return;
3024      } else {
3025         if (texture_error_check(ctx, dims, target, texObj, level, internalFormat,
3026                                 format, type, width, height, depth, border,
3027                                 pixels))
3028            return;
3029      }
3030   }
3031   assert(texObj);
3032
3033   /* Here we convert a cpal compressed image into a regular glTexImage2D
3034    * call by decompressing the texture.  If we really want to support cpal
3035    * textures in any driver this would have to be changed.
3036    */
3037   if (ctx->API == API_OPENGLES && compressed && dims == 2) {
3038      switch (internalFormat) {
3039      case GL_PALETTE4_RGB8_OES:
3040      case GL_PALETTE4_RGBA8_OES:
3041      case GL_PALETTE4_R5_G6_B5_OES:
3042      case GL_PALETTE4_RGBA4_OES:
3043      case GL_PALETTE4_RGB5_A1_OES:
3044      case GL_PALETTE8_RGB8_OES:
3045      case GL_PALETTE8_RGBA8_OES:
3046      case GL_PALETTE8_R5_G6_B5_OES:
3047      case GL_PALETTE8_RGBA4_OES:
3048      case GL_PALETTE8_RGB5_A1_OES:
3049         _mesa_cpal_compressed_teximage2d(target, level, internalFormat,
3050                                          width, height, imageSize, pixels);
3051         return;
3052      }
3053   }
3054
3055   if (compressed) {
3056      /* For glCompressedTexImage() the driver has no choice about the
3057       * texture format since we'll never transcode the user's compressed
3058       * image data.  The internalFormat was error checked earlier.
3059       */
3060      texFormat = _mesa_glenum_to_compressed_format(internalFormat);
3061   }
3062   else {
3063      /* In case of HALF_FLOAT_OES or FLOAT_OES, find corresponding sized
3064       * internal floating point format for the given base format.
3065       */
3066      if (_mesa_is_gles(ctx) && format == internalFormat) {
3067         if (type == GL_FLOAT) {
3068            texObj->_IsFloat = GL_TRUE;
3069         } else if (type == GL_HALF_FLOAT_OES || type == GL_HALF_FLOAT) {
3070            texObj->_IsHalfFloat = GL_TRUE;
3071         }
3072
3073         internalFormat = adjust_for_oes_float_texture(ctx, format, type);
3074      }
3075
3076      texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
3077                                              internalFormat, format, type);
3078   }
3079
3080   assert(texFormat != MESA_FORMAT_NONE);
3081
3082   if (!no_error) {
3083      /* check that width, height, depth are legal for the mipmap level */
3084      dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, level, width,
3085                                                    height, depth, border);
3086
3087      /* check that the texture won't take too much memory, etc */
3088      sizeOK = st_TestProxyTexImage(ctx, proxy_target(target),
3089                                    0, level, texFormat, 1,
3090                                    width, height, depth);
3091   }
3092
3093   if (_mesa_is_proxy_texture(target)) {
3094      /* Proxy texture: just clear or set state depending on error checking */
3095      struct gl_texture_image *texImage =
3096         get_proxy_tex_image(ctx, target, level);
3097
3098      if (!texImage)
3099         return;  /* GL_OUT_OF_MEMORY already recorded */
3100
3101      if (dimensionsOK && sizeOK) {
3102         _mesa_init_teximage_fields(ctx, texImage, width, height, depth,
3103                                    border, internalFormat, texFormat);
3104      }
3105      else {
3106         clear_teximage_fields(texImage);
3107      }
3108   }
3109   else {
3110      /* non-proxy target */
3111      const GLuint face = _mesa_tex_target_to_face(target);
3112      struct gl_texture_image *texImage;
3113
3114      if (!dimensionsOK) {
3115         _mesa_error(ctx, GL_INVALID_VALUE,
3116                     "%s%uD(invalid width=%d or height=%d or depth=%d)",
3117                     func, dims, width, height, depth);
3118         return;
3119      }
3120
3121      if (!sizeOK) {
3122         _mesa_error(ctx, GL_OUT_OF_MEMORY,
3123                     "%s%uD(image too large: %d x %d x %d, %s format)",
3124                     func, dims, width, height, depth,
3125                     _mesa_enum_to_string(internalFormat));
3126         return;
3127      }
3128
3129      /* Allow a hardware driver to just strip out the border, to provide
3130       * reliable but slightly incorrect hardware rendering instead of
3131       * rarely-tested software fallback rendering.
3132       */
3133      if (border) {
3134         strip_texture_border(target, &width, &height, &depth, unpack,
3135                              &unpack_no_border);
3136         border = 0;
3137         unpack = &unpack_no_border;
3138      }
3139
3140      _mesa_update_pixel(ctx);
3141
3142      _mesa_lock_texture(ctx, texObj);
3143      {
3144         texObj->External = GL_FALSE;
3145
3146         texImage = _mesa_get_tex_image(ctx, texObj, target, level);
3147
3148         if (!texImage) {
3149            _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims);
3150         }
3151         else {
3152            st_FreeTextureImageBuffer(ctx, texImage);
3153
3154            _mesa_init_teximage_fields(ctx, texImage,
3155                                       width, height, depth,
3156                                       border, internalFormat, texFormat);
3157
3158            /* Give the texture to the driver.  <pixels> may be null. */
3159            if (width > 0 && height > 0 && depth > 0) {
3160               if (compressed) {
3161                  st_CompressedTexImage(ctx, dims, texImage,
3162                                        imageSize, pixels);
3163               }
3164               else {
3165                  st_TexImage(ctx, dims, texImage, format,
3166                              type, pixels, unpack);
3167               }
3168            }
3169
3170            check_gen_mipmap(ctx, target, texObj, level);
3171
3172            _mesa_update_fbo_texture(ctx, texObj, face, level);
3173
3174            _mesa_dirty_texobj(ctx, texObj);
3175         }
3176      }
3177      _mesa_unlock_texture(ctx, texObj);
3178   }
3179}
3180
3181
3182/* This is a wrapper around teximage() so that we can force the KHR_no_error
3183 * logic to be inlined without inlining the function into all the callers.
3184 */
3185static void
3186teximage_err(struct gl_context *ctx, GLboolean compressed, GLuint dims,
3187             GLenum target, GLint level, GLint internalFormat,
3188             GLsizei width, GLsizei height, GLsizei depth,
3189             GLint border, GLenum format, GLenum type,
3190             GLsizei imageSize, const GLvoid *pixels)
3191{
3192   teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height,
3193            depth, border, format, type, imageSize, pixels, false);
3194}
3195
3196
3197static void
3198teximage_no_error(struct gl_context *ctx, GLboolean compressed, GLuint dims,
3199                  GLenum target, GLint level, GLint internalFormat,
3200                  GLsizei width, GLsizei height, GLsizei depth,
3201                  GLint border, GLenum format, GLenum type,
3202                  GLsizei imageSize, const GLvoid *pixels)
3203{
3204   teximage(ctx, compressed, dims, NULL, target, level, internalFormat, width, height,
3205            depth, border, format, type, imageSize, pixels, true);
3206}
3207
3208
3209/*
3210 * Called from the API.  Note that width includes the border.
3211 */
3212void GLAPIENTRY
3213_mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
3214                  GLsizei width, GLint border, GLenum format,
3215                  GLenum type, const GLvoid *pixels )
3216{
3217   GET_CURRENT_CONTEXT(ctx);
3218   teximage_err(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1, 1,
3219                border, format, type, 0, pixels);
3220}
3221
3222void GLAPIENTRY
3223_mesa_TextureImage1DEXT(GLuint texture, GLenum target, GLint level,
3224                      GLint internalFormat, GLsizei width, GLint border,
3225                      GLenum format, GLenum type, const GLvoid *pixels )
3226{
3227   struct gl_texture_object*  texObj;
3228   GET_CURRENT_CONTEXT(ctx);
3229
3230   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
3231                                           "glTextureImage1DEXT");
3232   if (!texObj)
3233      return;
3234   teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat,
3235            width, 1, 1, border, format, type, 0, pixels, false);
3236}
3237
3238void GLAPIENTRY
3239_mesa_MultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level,
3240                         GLint internalFormat, GLsizei width, GLint border,
3241                         GLenum format, GLenum type, const GLvoid *pixels )
3242{
3243   struct gl_texture_object*  texObj;
3244   GET_CURRENT_CONTEXT(ctx);
3245
3246   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
3247                                                   texunit - GL_TEXTURE0,
3248                                                   true,
3249                                                   "glMultiTexImage1DEXT");
3250   if (!texObj)
3251      return;
3252   teximage(ctx, GL_FALSE, 1, texObj, target, level, internalFormat, width, 1, 1,
3253                border, format, type, 0, pixels, false);
3254}
3255
3256void GLAPIENTRY
3257_mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
3258                  GLsizei width, GLsizei height, GLint border,
3259                  GLenum format, GLenum type,
3260                  const GLvoid *pixels )
3261{
3262   GET_CURRENT_CONTEXT(ctx);
3263   teximage_err(ctx, GL_FALSE, 2, target, level, internalFormat, width, height, 1,
3264                border, format, type, 0, pixels);
3265}
3266
3267void GLAPIENTRY
3268_mesa_TextureImage2DEXT(GLuint texture, GLenum target, GLint level,
3269                      GLint internalFormat, GLsizei width, GLsizei height,
3270                      GLint border,
3271                      GLenum format, GLenum type, const GLvoid *pixels )
3272{
3273   struct gl_texture_object*  texObj;
3274   GET_CURRENT_CONTEXT(ctx);
3275
3276   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
3277                                           "glTextureImage2DEXT");
3278   if (!texObj)
3279      return;
3280   teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat,
3281            width, height, 1, border, format, type, 0, pixels, false);
3282}
3283
3284void GLAPIENTRY
3285_mesa_MultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level,
3286                         GLint internalFormat, GLsizei width, GLsizei height,
3287                         GLint border,
3288                         GLenum format, GLenum type, const GLvoid *pixels )
3289{
3290   struct gl_texture_object*  texObj;
3291   GET_CURRENT_CONTEXT(ctx);
3292
3293   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
3294                                                   texunit - GL_TEXTURE0,
3295                                                   true,
3296                                                   "glMultiTexImage2DEXT");
3297   if (!texObj)
3298      return;
3299   teximage(ctx, GL_FALSE, 2, texObj, target, level, internalFormat, width, height, 1,
3300                border, format, type, 0, pixels, false);
3301}
3302
3303/*
3304 * Called by the API or display list executor.
3305 * Note that width and height include the border.
3306 */
3307void GLAPIENTRY
3308_mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
3309                  GLsizei width, GLsizei height, GLsizei depth,
3310                  GLint border, GLenum format, GLenum type,
3311                  const GLvoid *pixels )
3312{
3313   GET_CURRENT_CONTEXT(ctx);
3314   teximage_err(ctx, GL_FALSE, 3, target, level, internalFormat,
3315                width, height, depth, border, format, type, 0, pixels);
3316}
3317
3318void GLAPIENTRY
3319_mesa_TextureImage3DEXT(GLuint texture, GLenum target, GLint level,
3320                      GLint internalFormat, GLsizei width, GLsizei height,
3321                      GLsizei depth, GLint border,
3322                      GLenum format, GLenum type, const GLvoid *pixels )
3323{
3324   struct gl_texture_object*  texObj;
3325   GET_CURRENT_CONTEXT(ctx);
3326
3327   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
3328                                           "glTextureImage3DEXT");
3329   if (!texObj)
3330      return;
3331   teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat,
3332            width, height, depth, border, format, type, 0, pixels, false);
3333}
3334
3335
3336void GLAPIENTRY
3337_mesa_MultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level,
3338                         GLint internalFormat, GLsizei width, GLsizei height,
3339                         GLsizei depth, GLint border, GLenum format, GLenum type,
3340                         const GLvoid *pixels )
3341{
3342   struct gl_texture_object*  texObj;
3343   GET_CURRENT_CONTEXT(ctx);
3344
3345   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
3346                                                   texunit - GL_TEXTURE0,
3347                                                   true,
3348                                                   "glMultiTexImage3DEXT");
3349   if (!texObj)
3350      return;
3351   teximage(ctx, GL_FALSE, 3, texObj, target, level, internalFormat,
3352                width, height, depth, border, format, type, 0, pixels, false);
3353}
3354
3355
3356void GLAPIENTRY
3357_mesa_TexImage1D_no_error(GLenum target, GLint level, GLint internalFormat,
3358                          GLsizei width, GLint border, GLenum format,
3359                          GLenum type, const GLvoid *pixels)
3360{
3361   GET_CURRENT_CONTEXT(ctx);
3362   teximage_no_error(ctx, GL_FALSE, 1, target, level, internalFormat, width, 1,
3363                     1, border, format, type, 0, pixels);
3364}
3365
3366
3367void GLAPIENTRY
3368_mesa_TexImage2D_no_error(GLenum target, GLint level, GLint internalFormat,
3369                          GLsizei width, GLsizei height, GLint border,
3370                          GLenum format, GLenum type, const GLvoid *pixels)
3371{
3372   GET_CURRENT_CONTEXT(ctx);
3373   teximage_no_error(ctx, GL_FALSE, 2, target, level, internalFormat, width,
3374                     height, 1, border, format, type, 0, pixels);
3375}
3376
3377
3378void GLAPIENTRY
3379_mesa_TexImage3D_no_error(GLenum target, GLint level, GLint internalFormat,
3380                          GLsizei width, GLsizei height, GLsizei depth,
3381                          GLint border, GLenum format, GLenum type,
3382                          const GLvoid *pixels )
3383{
3384   GET_CURRENT_CONTEXT(ctx);
3385   teximage_no_error(ctx, GL_FALSE, 3, target, level, internalFormat,
3386                     width, height, depth, border, format, type, 0, pixels);
3387}
3388
3389/*
3390 * Helper used by __mesa_EGLImageTargetTexture2DOES and
3391 * _mesa_EGLImageTargetTexStorageEXT.
3392 */
3393static void
3394egl_image_target_texture(struct gl_context *ctx,
3395                         struct gl_texture_object *texObj, GLenum target,
3396                         GLeglImageOES image, bool tex_storage,
3397                         const char *caller)
3398{
3399   struct gl_texture_image *texImage;
3400   bool valid_target;
3401   FLUSH_VERTICES(ctx, 0, 0);
3402
3403   switch (target) {
3404   case GL_TEXTURE_2D:
3405      valid_target = _mesa_has_OES_EGL_image(ctx) ||
3406                     (tex_storage && _mesa_has_EXT_EGL_image_storage(ctx));
3407      break;
3408   case GL_TEXTURE_EXTERNAL_OES:
3409      valid_target = _mesa_has_OES_EGL_image_external(ctx);
3410      break;
3411   default:
3412      valid_target = false;
3413      break;
3414   }
3415
3416   if (!valid_target) {
3417      _mesa_error(ctx, tex_storage ? GL_INVALID_OPERATION : GL_INVALID_ENUM, "%s(target=%d)", caller, target);
3418      return;
3419   }
3420
3421   if (!texObj)
3422      texObj = _mesa_get_current_tex_object(ctx, target);
3423   if (!texObj)
3424      return;
3425
3426   if (!image || (ctx->Driver.ValidateEGLImage &&
3427                  !ctx->Driver.ValidateEGLImage(ctx, image))) {
3428      _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image);
3429      return;
3430   }
3431
3432   _mesa_lock_texture(ctx, texObj);
3433
3434   if (texObj->Immutable) {
3435      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture is immutable)", caller);
3436      _mesa_unlock_texture(ctx, texObj);
3437      return;
3438   }
3439
3440   texImage = _mesa_get_tex_image(ctx, texObj, target, 0);
3441   if (!texImage) {
3442      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
3443   } else {
3444      st_FreeTextureImageBuffer(ctx, texImage);
3445
3446      texObj->External = GL_TRUE;
3447
3448      if (tex_storage) {
3449         st_egl_image_target_tex_storage(ctx, target, texObj, texImage,
3450                                         image);
3451      } else {
3452         st_egl_image_target_texture_2d(ctx, target, texObj, texImage,
3453                                        image);
3454      }
3455
3456      _mesa_dirty_texobj(ctx, texObj);
3457   }
3458
3459   if (tex_storage)
3460      _mesa_set_texture_view_state(ctx, texObj, target, 1);
3461
3462   _mesa_update_fbo_texture(ctx, texObj, 0, 0);
3463
3464   _mesa_unlock_texture(ctx, texObj);
3465}
3466
3467void GLAPIENTRY
3468_mesa_EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
3469{
3470   const char *func = "glEGLImageTargetTexture2D";
3471   GET_CURRENT_CONTEXT(ctx);
3472
3473   egl_image_target_texture(ctx, NULL, target, image, false, func);
3474}
3475
3476static void
3477egl_image_target_texture_storage(struct gl_context *ctx,
3478                                 struct gl_texture_object *texObj, GLenum target,
3479                                 GLeglImageOES image, const GLint *attrib_list,
3480                                 const char *caller)
3481{
3482   /*
3483    * EXT_EGL_image_storage:
3484    *
3485    * "<attrib_list> must be NULL or a pointer to the value GL_NONE."
3486    */
3487   if (attrib_list && attrib_list[0] != GL_NONE) {
3488      _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image);
3489      return;
3490   }
3491
3492   egl_image_target_texture(ctx, texObj, target, image, true, caller);
3493}
3494
3495
3496void GLAPIENTRY
3497_mesa_EGLImageTargetTexStorageEXT(GLenum target, GLeglImageOES image,
3498                                  const GLint *attrib_list)
3499{
3500   const char *func = "glEGLImageTargetTexStorageEXT";
3501   GET_CURRENT_CONTEXT(ctx);
3502
3503   egl_image_target_texture_storage(ctx, NULL, target, image, attrib_list,
3504                                    func);
3505}
3506
3507void GLAPIENTRY
3508_mesa_EGLImageTargetTextureStorageEXT(GLuint texture, GLeglImageOES image,
3509                                      const GLint *attrib_list)
3510{
3511   struct gl_texture_object *texObj;
3512   const char *func = "glEGLImageTargetTextureStorageEXT";
3513   GET_CURRENT_CONTEXT(ctx);
3514
3515   if (!(_mesa_is_desktop_gl(ctx) && ctx->Version >= 45) &&
3516       !_mesa_has_ARB_direct_state_access(ctx) &&
3517       !_mesa_has_EXT_direct_state_access(ctx)) {
3518      _mesa_error(ctx, GL_INVALID_OPERATION, "direct access not supported");
3519      return;
3520   }
3521
3522   texObj = _mesa_lookup_texture_err(ctx, texture, func);
3523   if (!texObj)
3524      return;
3525
3526   egl_image_target_texture_storage(ctx, texObj, texObj->Target, image,
3527                                    attrib_list, func);
3528}
3529
3530/**
3531 * Helper that implements the glTexSubImage1/2/3D()
3532 * and glTextureSubImage1/2/3D() functions.
3533 */
3534static void
3535texture_sub_image(struct gl_context *ctx, GLuint dims,
3536                  struct gl_texture_object *texObj,
3537                  struct gl_texture_image *texImage,
3538                  GLenum target, GLint level,
3539                  GLint xoffset, GLint yoffset, GLint zoffset,
3540                  GLsizei width, GLsizei height, GLsizei depth,
3541                  GLenum format, GLenum type, const GLvoid *pixels)
3542{
3543   FLUSH_VERTICES(ctx, 0, 0);
3544
3545   _mesa_update_pixel(ctx);
3546
3547   _mesa_lock_texture(ctx, texObj);
3548   {
3549      if (width > 0 && height > 0 && depth > 0) {
3550         /* If we have a border, offset=-1 is legal.  Bias by border width. */
3551         switch (dims) {
3552         case 3:
3553            if (target != GL_TEXTURE_2D_ARRAY)
3554               zoffset += texImage->Border;
3555            FALLTHROUGH;
3556         case 2:
3557            if (target != GL_TEXTURE_1D_ARRAY)
3558               yoffset += texImage->Border;
3559            FALLTHROUGH;
3560         case 1:
3561            xoffset += texImage->Border;
3562         }
3563
3564         st_TexSubImage(ctx, dims, texImage,
3565                        xoffset, yoffset, zoffset,
3566                        width, height, depth,
3567                        format, type, pixels, &ctx->Unpack);
3568
3569         check_gen_mipmap(ctx, target, texObj, level);
3570
3571         /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
3572          * the texel data, not the texture format, size, etc.
3573          */
3574      }
3575   }
3576   _mesa_unlock_texture(ctx, texObj);
3577}
3578
3579/**
3580 * Implement all the glTexSubImage1/2/3D() functions.
3581 * Must split this out this way because of GL_TEXTURE_CUBE_MAP.
3582 */
3583static void
3584texsubimage_err(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
3585                GLint xoffset, GLint yoffset, GLint zoffset,
3586                GLsizei width, GLsizei height, GLsizei depth,
3587                GLenum format, GLenum type, const GLvoid *pixels,
3588                const char *callerName)
3589{
3590   struct gl_texture_object *texObj;
3591   struct gl_texture_image *texImage;
3592
3593   /* check target (proxies not allowed) */
3594   if (!legal_texsubimage_target(ctx, dims, target, false)) {
3595      _mesa_error(ctx, GL_INVALID_ENUM, "glTexSubImage%uD(target=%s)",
3596                  dims, _mesa_enum_to_string(target));
3597      return;
3598   }
3599
3600   texObj = _mesa_get_current_tex_object(ctx, target);
3601   if (!texObj)
3602      return;
3603
3604   if (texsubimage_error_check(ctx, dims, texObj, target, level,
3605                               xoffset, yoffset, zoffset,
3606                               width, height, depth, format, type,
3607                               pixels, callerName)) {
3608      return;   /* error was detected */
3609   }
3610
3611   texImage = _mesa_select_tex_image(texObj, target, level);
3612   /* texsubimage_error_check ensures that texImage is not NULL */
3613
3614   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3615      _mesa_debug(ctx, "glTexSubImage%uD %s %d %d %d %d %d %d %d %s %s %p\n",
3616                  dims,
3617                  _mesa_enum_to_string(target), level,
3618                  xoffset, yoffset, zoffset, width, height, depth,
3619                  _mesa_enum_to_string(format),
3620                  _mesa_enum_to_string(type), pixels);
3621
3622   texture_sub_image(ctx, dims, texObj, texImage, target, level,
3623                     xoffset, yoffset, zoffset, width, height, depth,
3624                     format, type, pixels);
3625}
3626
3627
3628static void
3629texsubimage(struct gl_context *ctx, GLuint dims, GLenum target, GLint level,
3630            GLint xoffset, GLint yoffset, GLint zoffset,
3631            GLsizei width, GLsizei height, GLsizei depth,
3632            GLenum format, GLenum type, const GLvoid *pixels)
3633{
3634   struct gl_texture_object *texObj;
3635   struct gl_texture_image *texImage;
3636
3637   texObj = _mesa_get_current_tex_object(ctx, target);
3638   texImage = _mesa_select_tex_image(texObj, target, level);
3639
3640   texture_sub_image(ctx, dims, texObj, texImage, target, level,
3641                     xoffset, yoffset, zoffset, width, height, depth,
3642                     format, type, pixels);
3643}
3644
3645
3646/**
3647 * Implement all the glTextureSubImage1/2/3D() functions.
3648 * Must split this out this way because of GL_TEXTURE_CUBE_MAP.
3649 */
3650static ALWAYS_INLINE void
3651texturesubimage(struct gl_context *ctx, GLuint dims,
3652                GLuint texture, GLenum target, GLint level,
3653                GLint xoffset, GLint yoffset, GLint zoffset,
3654                GLsizei width, GLsizei height, GLsizei depth,
3655                GLenum format, GLenum type, const GLvoid *pixels,
3656                const char *callerName, bool no_error, bool ext_dsa)
3657{
3658   struct gl_texture_object *texObj;
3659   struct gl_texture_image *texImage;
3660   int i;
3661
3662   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
3663      _mesa_debug(ctx,
3664                  "glTextureSubImage%uD %d %d %d %d %d %d %d %d %s %s %p\n",
3665                  dims, texture, level,
3666                  xoffset, yoffset, zoffset, width, height, depth,
3667                  _mesa_enum_to_string(format),
3668                  _mesa_enum_to_string(type), pixels);
3669
3670   /* Get the texture object by Name. */
3671   if (!no_error) {
3672      if (!ext_dsa) {
3673         texObj = _mesa_lookup_texture_err(ctx, texture, callerName);
3674      } else {
3675         texObj = lookup_texture_ext_dsa(ctx, target, texture, callerName);
3676      }
3677      if (!texObj)
3678         return;
3679   } else {
3680      texObj = _mesa_lookup_texture(ctx, texture);
3681   }
3682
3683   if (!no_error) {
3684      /* check target (proxies not allowed) */
3685      if (!legal_texsubimage_target(ctx, dims, texObj->Target, true)) {
3686         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target=%s)",
3687                     callerName, _mesa_enum_to_string(texObj->Target));
3688         return;
3689      }
3690
3691      if (texsubimage_error_check(ctx, dims, texObj, texObj->Target, level,
3692                                  xoffset, yoffset, zoffset,
3693                                  width, height, depth, format, type,
3694                                  pixels, callerName)) {
3695         return;   /* error was detected */
3696      }
3697   }
3698
3699   /* Must handle special case GL_TEXTURE_CUBE_MAP. */
3700   if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
3701      GLint imageStride;
3702
3703      /*
3704       * What do we do if the user created a texture with the following code
3705       * and then called this function with its handle?
3706       *
3707       *    GLuint tex;
3708       *    glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &tex);
3709       *    glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
3710       *    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, ...);
3711       *    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, ...);
3712       *    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, ...);
3713       *    // Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set, or given the
3714       *    // wrong format, or given the wrong size, etc.
3715       *    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, ...);
3716       *    glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, ...);
3717       *
3718       * A bug has been filed against the spec for this case.  In the
3719       * meantime, we will check for cube completeness.
3720       *
3721       * According to Section 8.17 Texture Completeness in the OpenGL 4.5
3722       * Core Profile spec (30.10.2014):
3723       *    "[A] cube map texture is cube complete if the
3724       *    following conditions all hold true: The [base level] texture
3725       *    images of each of the six cube map faces have identical, positive,
3726       *    and square dimensions. The [base level] images were each specified
3727       *    with the same internal format."
3728       *
3729       * It seems reasonable to check for cube completeness of an arbitrary
3730       * level here so that the image data has a consistent format and size.
3731       */
3732      if (!no_error && !_mesa_cube_level_complete(texObj, level)) {
3733         _mesa_error(ctx, GL_INVALID_OPERATION,
3734                     "glTextureSubImage%uD(cube map incomplete)",
3735                     dims);
3736         return;
3737      }
3738
3739      imageStride = _mesa_image_image_stride(&ctx->Unpack, width, height,
3740                                             format, type);
3741      /* Copy in each face. */
3742      for (i = zoffset; i < zoffset + depth; ++i) {
3743         texImage = texObj->Image[i][level];
3744         assert(texImage);
3745
3746         texture_sub_image(ctx, 3, texObj, texImage, texObj->Target,
3747                           level, xoffset, yoffset, 0,
3748                           width, height, 1, format,
3749                           type, pixels);
3750         pixels = (GLubyte *) pixels + imageStride;
3751      }
3752   }
3753   else {
3754      texImage = _mesa_select_tex_image(texObj, texObj->Target, level);
3755      assert(texImage);
3756
3757      texture_sub_image(ctx, dims, texObj, texImage, texObj->Target,
3758                        level, xoffset, yoffset, zoffset,
3759                        width, height, depth, format,
3760                        type, pixels);
3761   }
3762}
3763
3764
3765static void
3766texturesubimage_error(struct gl_context *ctx, GLuint dims,
3767                      GLuint texture, GLenum target, GLint level,
3768                      GLint xoffset, GLint yoffset, GLint zoffset,
3769                      GLsizei width, GLsizei height, GLsizei depth,
3770                      GLenum format, GLenum type, const GLvoid *pixels,
3771                      const char *callerName, bool ext_dsa)
3772{
3773   texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset,
3774                   zoffset, width, height, depth, format, type, pixels,
3775                   callerName, false, ext_dsa);
3776}
3777
3778
3779static void
3780texturesubimage_no_error(struct gl_context *ctx, GLuint dims,
3781                         GLuint texture, GLenum target, GLint level,
3782                         GLint xoffset, GLint yoffset, GLint zoffset,
3783                         GLsizei width, GLsizei height, GLsizei depth,
3784                         GLenum format, GLenum type, const GLvoid *pixels,
3785                         const char *callerName, bool ext_dsa)
3786{
3787   texturesubimage(ctx, dims, texture, target, level, xoffset, yoffset,
3788                   zoffset, width, height, depth, format, type, pixels,
3789                   callerName, true, ext_dsa);
3790}
3791
3792
3793void GLAPIENTRY
3794_mesa_TexSubImage1D_no_error(GLenum target, GLint level,
3795                             GLint xoffset, GLsizei width,
3796                             GLenum format, GLenum type,
3797                             const GLvoid *pixels)
3798{
3799   GET_CURRENT_CONTEXT(ctx);
3800   texsubimage(ctx, 1, target, level,
3801               xoffset, 0, 0,
3802               width, 1, 1,
3803               format, type, pixels);
3804}
3805
3806
3807void GLAPIENTRY
3808_mesa_TexSubImage1D( GLenum target, GLint level,
3809                     GLint xoffset, GLsizei width,
3810                     GLenum format, GLenum type,
3811                     const GLvoid *pixels )
3812{
3813   GET_CURRENT_CONTEXT(ctx);
3814   texsubimage_err(ctx, 1, target, level,
3815                   xoffset, 0, 0,
3816                   width, 1, 1,
3817                   format, type, pixels, "glTexSubImage1D");
3818}
3819
3820
3821void GLAPIENTRY
3822_mesa_TexSubImage2D_no_error(GLenum target, GLint level,
3823                             GLint xoffset, GLint yoffset,
3824                             GLsizei width, GLsizei height,
3825                             GLenum format, GLenum type,
3826                             const GLvoid *pixels)
3827{
3828   GET_CURRENT_CONTEXT(ctx);
3829   texsubimage(ctx, 2, target, level,
3830               xoffset, yoffset, 0,
3831               width, height, 1,
3832               format, type, pixels);
3833}
3834
3835
3836void GLAPIENTRY
3837_mesa_TexSubImage2D( GLenum target, GLint level,
3838                     GLint xoffset, GLint yoffset,
3839                     GLsizei width, GLsizei height,
3840                     GLenum format, GLenum type,
3841                     const GLvoid *pixels )
3842{
3843   GET_CURRENT_CONTEXT(ctx);
3844   texsubimage_err(ctx, 2, target, level,
3845                   xoffset, yoffset, 0,
3846                   width, height, 1,
3847                   format, type, pixels, "glTexSubImage2D");
3848}
3849
3850
3851void GLAPIENTRY
3852_mesa_TexSubImage3D_no_error(GLenum target, GLint level,
3853                             GLint xoffset, GLint yoffset, GLint zoffset,
3854                             GLsizei width, GLsizei height, GLsizei depth,
3855                             GLenum format, GLenum type,
3856                             const GLvoid *pixels)
3857{
3858   GET_CURRENT_CONTEXT(ctx);
3859   texsubimage(ctx, 3, target, level,
3860               xoffset, yoffset, zoffset,
3861               width, height, depth,
3862               format, type, pixels);
3863}
3864
3865
3866void GLAPIENTRY
3867_mesa_TexSubImage3D( GLenum target, GLint level,
3868                     GLint xoffset, GLint yoffset, GLint zoffset,
3869                     GLsizei width, GLsizei height, GLsizei depth,
3870                     GLenum format, GLenum type,
3871                     const GLvoid *pixels )
3872{
3873   GET_CURRENT_CONTEXT(ctx);
3874   texsubimage_err(ctx, 3, target, level,
3875                   xoffset, yoffset, zoffset,
3876                   width, height, depth,
3877                   format, type, pixels, "glTexSubImage3D");
3878}
3879
3880
3881void GLAPIENTRY
3882_mesa_TextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset,
3883                                 GLsizei width, GLenum format, GLenum type,
3884                                 const GLvoid *pixels)
3885{
3886   GET_CURRENT_CONTEXT(ctx);
3887   texturesubimage_no_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width,
3888                            1, 1, format, type, pixels, "glTextureSubImage1D",
3889                            false);
3890}
3891
3892
3893void GLAPIENTRY
3894_mesa_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level,
3895                        GLint xoffset, GLsizei width,
3896                        GLenum format, GLenum type,
3897                        const GLvoid *pixels)
3898{
3899   GET_CURRENT_CONTEXT(ctx);
3900   texturesubimage_error(ctx, 1, texture, target, level, xoffset, 0, 0, width, 1,
3901                         1, format, type, pixels, "glTextureSubImage1DEXT",
3902                         false);
3903}
3904
3905
3906void GLAPIENTRY
3907_mesa_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level,
3908                            GLint xoffset, GLsizei width,
3909                            GLenum format, GLenum type,
3910                            const GLvoid *pixels)
3911{
3912   GET_CURRENT_CONTEXT(ctx);
3913   struct gl_texture_object *texObj;
3914   struct gl_texture_image *texImage;
3915
3916   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
3917                                                   texunit - GL_TEXTURE0,
3918                                                   false,
3919                                                   "glMultiTexImage1DEXT");
3920   texImage = _mesa_select_tex_image(texObj, target, level);
3921
3922   texture_sub_image(ctx, 1, texObj, texImage, target, level,
3923                     xoffset, 0, 0, width, 1, 1,
3924                     format, type, pixels);
3925}
3926
3927
3928void GLAPIENTRY
3929_mesa_TextureSubImage1D(GLuint texture, GLint level,
3930                        GLint xoffset, GLsizei width,
3931                        GLenum format, GLenum type,
3932                        const GLvoid *pixels)
3933{
3934   GET_CURRENT_CONTEXT(ctx);
3935   texturesubimage_error(ctx, 1, texture, 0, level, xoffset, 0, 0, width, 1,
3936                         1, format, type, pixels, "glTextureSubImage1D",
3937                         false);
3938}
3939
3940
3941void GLAPIENTRY
3942_mesa_TextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset,
3943                                 GLint yoffset, GLsizei width, GLsizei height,
3944                                 GLenum format, GLenum type,
3945                                 const GLvoid *pixels)
3946{
3947   GET_CURRENT_CONTEXT(ctx);
3948   texturesubimage_no_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0,
3949                            width, height, 1, format, type, pixels,
3950                            "glTextureSubImage2D", false);
3951}
3952
3953
3954void GLAPIENTRY
3955_mesa_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
3956                           GLint xoffset, GLint yoffset, GLsizei width,
3957                           GLsizei height, GLenum format, GLenum type,
3958                           const GLvoid *pixels)
3959{
3960   GET_CURRENT_CONTEXT(ctx);
3961   texturesubimage_error(ctx, 2, texture, target, level, xoffset, yoffset, 0,
3962                         width, height, 1, format, type, pixels,
3963                         "glTextureSubImage2DEXT", true);
3964}
3965
3966
3967void GLAPIENTRY
3968_mesa_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level,
3969                            GLint xoffset, GLint yoffset, GLsizei width,
3970                            GLsizei height, GLenum format, GLenum type,
3971                            const GLvoid *pixels)
3972{
3973   GET_CURRENT_CONTEXT(ctx);
3974   struct gl_texture_object *texObj;
3975   struct gl_texture_image *texImage;
3976
3977   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
3978                                                   texunit - GL_TEXTURE0,
3979                                                   false,
3980                                                   "glMultiTexImage2DEXT");
3981   texImage = _mesa_select_tex_image(texObj, target, level);
3982
3983   texture_sub_image(ctx, 2, texObj, texImage, target, level,
3984                     xoffset, yoffset, 0, width, height, 1,
3985                     format, type, pixels);
3986}
3987
3988
3989void GLAPIENTRY
3990_mesa_TextureSubImage2D(GLuint texture, GLint level,
3991                        GLint xoffset, GLint yoffset,
3992                        GLsizei width, GLsizei height,
3993                        GLenum format, GLenum type,
3994                        const GLvoid *pixels)
3995{
3996   GET_CURRENT_CONTEXT(ctx);
3997   texturesubimage_error(ctx, 2, texture, 0, level, xoffset, yoffset, 0,
3998                         width, height, 1, format, type, pixels,
3999                         "glTextureSubImage2D", false);
4000}
4001
4002
4003void GLAPIENTRY
4004_mesa_TextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset,
4005                                 GLint yoffset, GLint zoffset, GLsizei width,
4006                                 GLsizei height, GLsizei depth, GLenum format,
4007                                 GLenum type, const GLvoid *pixels)
4008{
4009   GET_CURRENT_CONTEXT(ctx);
4010   texturesubimage_no_error(ctx, 3, texture, 0, level, xoffset, yoffset,
4011                            zoffset, width, height, depth, format, type,
4012                            pixels, "glTextureSubImage3D", false);
4013}
4014
4015
4016void GLAPIENTRY
4017_mesa_TextureSubImage3DEXT(GLuint texture, GLenum target, GLint level,
4018                           GLint xoffset, GLint yoffset, GLint zoffset,
4019                           GLsizei width, GLsizei height, GLsizei depth,
4020                           GLenum format, GLenum type, const GLvoid *pixels)
4021{
4022   GET_CURRENT_CONTEXT(ctx);
4023   texturesubimage_error(ctx, 3, texture, target, level, xoffset, yoffset,
4024                         zoffset, width, height, depth, format, type,
4025                         pixels, "glTextureSubImage3DEXT", true);
4026}
4027
4028
4029void GLAPIENTRY
4030_mesa_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level,
4031                           GLint xoffset, GLint yoffset, GLint zoffset,
4032                           GLsizei width, GLsizei height, GLsizei depth,
4033                           GLenum format, GLenum type, const GLvoid *pixels)
4034{
4035   GET_CURRENT_CONTEXT(ctx);
4036   struct gl_texture_object *texObj;
4037   struct gl_texture_image *texImage;
4038
4039   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
4040                                                   texunit - GL_TEXTURE0,
4041                                                   false,
4042                                                   "glMultiTexImage3DEXT");
4043   texImage = _mesa_select_tex_image(texObj, target, level);
4044
4045   texture_sub_image(ctx, 3, texObj, texImage, target, level,
4046                     xoffset, yoffset, zoffset, width, height, depth,
4047                     format, type, pixels);
4048}
4049
4050
4051void GLAPIENTRY
4052_mesa_TextureSubImage3D(GLuint texture, GLint level,
4053                        GLint xoffset, GLint yoffset, GLint zoffset,
4054                        GLsizei width, GLsizei height, GLsizei depth,
4055                        GLenum format, GLenum type,
4056                        const GLvoid *pixels)
4057{
4058   GET_CURRENT_CONTEXT(ctx);
4059   texturesubimage_error(ctx, 3, texture, 0, level, xoffset, yoffset, zoffset,
4060                         width, height, depth, format, type, pixels,
4061                         "glTextureSubImage3D", false);
4062}
4063
4064
4065/**
4066 * For glCopyTexSubImage, return the source renderbuffer to copy texel data
4067 * from.  This depends on whether the texture contains color or depth values.
4068 */
4069static struct gl_renderbuffer *
4070get_copy_tex_image_source(struct gl_context *ctx, mesa_format texFormat)
4071{
4072   if (_mesa_get_format_bits(texFormat, GL_DEPTH_BITS) > 0) {
4073      /* reading from depth/stencil buffer */
4074      return ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
4075   } else if (_mesa_get_format_bits(texFormat, GL_STENCIL_BITS) > 0) {
4076      return ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
4077   } else {
4078      /* copying from color buffer */
4079      return ctx->ReadBuffer->_ColorReadBuffer;
4080   }
4081}
4082
4083
4084static void
4085copytexsubimage_by_slice(struct gl_context *ctx,
4086                         struct gl_texture_image *texImage,
4087                         GLuint dims,
4088                         GLint xoffset, GLint yoffset, GLint zoffset,
4089                         struct gl_renderbuffer *rb,
4090                         GLint x, GLint y,
4091                         GLsizei width, GLsizei height)
4092{
4093   if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
4094      int slice;
4095
4096      /* For 1D arrays, we copy each scanline of the source rectangle into the
4097       * next array slice.
4098       */
4099      assert(zoffset == 0);
4100
4101      for (slice = 0; slice < height; slice++) {
4102         assert(yoffset + slice < texImage->Height);
4103         st_CopyTexSubImage(ctx, 2, texImage,
4104                            xoffset, 0, yoffset + slice,
4105                            rb, x, y + slice, width, 1);
4106      }
4107   } else {
4108      st_CopyTexSubImage(ctx, dims, texImage,
4109                         xoffset, yoffset, zoffset,
4110                         rb, x, y, width, height);
4111   }
4112}
4113
4114
4115static GLboolean
4116formats_differ_in_component_sizes(mesa_format f1, mesa_format f2)
4117{
4118   GLint f1_r_bits = _mesa_get_format_bits(f1, GL_RED_BITS);
4119   GLint f1_g_bits = _mesa_get_format_bits(f1, GL_GREEN_BITS);
4120   GLint f1_b_bits = _mesa_get_format_bits(f1, GL_BLUE_BITS);
4121   GLint f1_a_bits = _mesa_get_format_bits(f1, GL_ALPHA_BITS);
4122
4123   GLint f2_r_bits = _mesa_get_format_bits(f2, GL_RED_BITS);
4124   GLint f2_g_bits = _mesa_get_format_bits(f2, GL_GREEN_BITS);
4125   GLint f2_b_bits = _mesa_get_format_bits(f2, GL_BLUE_BITS);
4126   GLint f2_a_bits = _mesa_get_format_bits(f2, GL_ALPHA_BITS);
4127
4128   if ((f1_r_bits && f2_r_bits && f1_r_bits != f2_r_bits)
4129       || (f1_g_bits && f2_g_bits && f1_g_bits != f2_g_bits)
4130       || (f1_b_bits && f2_b_bits && f1_b_bits != f2_b_bits)
4131       || (f1_a_bits && f2_a_bits && f1_a_bits != f2_a_bits))
4132      return GL_TRUE;
4133
4134   return GL_FALSE;
4135}
4136
4137
4138/**
4139 * Check if the given texture format and size arguments match those
4140 * of the texture image.
4141 * \param return true if arguments match, false otherwise.
4142 */
4143static bool
4144can_avoid_reallocation(const struct gl_texture_image *texImage,
4145                       GLenum internalFormat,
4146                       mesa_format texFormat, GLsizei width,
4147                       GLsizei height, GLint border)
4148{
4149   if (texImage->InternalFormat != internalFormat)
4150      return false;
4151   if (texImage->TexFormat != texFormat)
4152      return false;
4153   if (texImage->Border != border)
4154      return false;
4155   if (texImage->Width2 != width)
4156      return false;
4157   if (texImage->Height2 != height)
4158      return false;
4159   return true;
4160}
4161
4162
4163/**
4164 * Implementation for glCopyTex(ture)SubImage1/2/3D() functions.
4165 */
4166static void
4167copy_texture_sub_image(struct gl_context *ctx, GLuint dims,
4168                       struct gl_texture_object *texObj,
4169                       GLenum target, GLint level,
4170                       GLint xoffset, GLint yoffset, GLint zoffset,
4171                       GLint x, GLint y, GLsizei width, GLsizei height)
4172{
4173   struct gl_texture_image *texImage;
4174
4175   _mesa_lock_texture(ctx, texObj);
4176
4177   texImage = _mesa_select_tex_image(texObj, target, level);
4178
4179   /* If we have a border, offset=-1 is legal.  Bias by border width. */
4180   switch (dims) {
4181   case 3:
4182      if (target != GL_TEXTURE_2D_ARRAY)
4183         zoffset += texImage->Border;
4184      FALLTHROUGH;
4185   case 2:
4186      if (target != GL_TEXTURE_1D_ARRAY)
4187         yoffset += texImage->Border;
4188      FALLTHROUGH;
4189   case 1:
4190      xoffset += texImage->Border;
4191   }
4192
4193   if (ctx->Const.NoClippingOnCopyTex ||
4194       _mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
4195                                  &width, &height)) {
4196      struct gl_renderbuffer *srcRb =
4197         get_copy_tex_image_source(ctx, texImage->TexFormat);
4198
4199      copytexsubimage_by_slice(ctx, texImage, dims, xoffset, yoffset, zoffset,
4200                               srcRb, x, y, width, height);
4201
4202      check_gen_mipmap(ctx, target, texObj, level);
4203
4204      /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
4205       * the texel data, not the texture format, size, etc.
4206       */
4207   }
4208
4209   _mesa_unlock_texture(ctx, texObj);
4210}
4211
4212
4213static void
4214copy_texture_sub_image_err(struct gl_context *ctx, GLuint dims,
4215                           struct gl_texture_object *texObj,
4216                           GLenum target, GLint level,
4217                           GLint xoffset, GLint yoffset, GLint zoffset,
4218                           GLint x, GLint y, GLsizei width, GLsizei height,
4219                           const char *caller)
4220{
4221   FLUSH_VERTICES(ctx, 0, 0);
4222
4223   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
4224      _mesa_debug(ctx, "%s %s %d %d %d %d %d %d %d %d\n", caller,
4225                  _mesa_enum_to_string(target),
4226                  level, xoffset, yoffset, zoffset, x, y, width, height);
4227
4228   _mesa_update_pixel(ctx);
4229
4230   if (ctx->NewState & _NEW_BUFFERS)
4231      _mesa_update_state(ctx);
4232
4233   if (copytexsubimage_error_check(ctx, dims, texObj, target, level,
4234                                   xoffset, yoffset, zoffset,
4235                                   width, height, caller)) {
4236      return;
4237   }
4238
4239   copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset,
4240                          zoffset, x, y, width, height);
4241}
4242
4243
4244static void
4245copy_texture_sub_image_no_error(struct gl_context *ctx, GLuint dims,
4246                                struct gl_texture_object *texObj,
4247                                GLenum target, GLint level,
4248                                GLint xoffset, GLint yoffset, GLint zoffset,
4249                                GLint x, GLint y, GLsizei width, GLsizei height)
4250{
4251   FLUSH_VERTICES(ctx, 0, 0);
4252
4253   _mesa_update_pixel(ctx);
4254
4255   if (ctx->NewState & _NEW_BUFFERS)
4256      _mesa_update_state(ctx);
4257
4258   copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset,
4259                          zoffset, x, y, width, height);
4260}
4261
4262
4263/**
4264 * Implement the glCopyTexImage1/2D() functions.
4265 */
4266static ALWAYS_INLINE void
4267copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texObj,
4268             GLenum target, GLint level, GLenum internalFormat,
4269             GLint x, GLint y, GLsizei width, GLsizei height, GLint border,
4270             bool no_error)
4271{
4272   struct gl_texture_image *texImage;
4273   mesa_format texFormat;
4274
4275   FLUSH_VERTICES(ctx, 0, 0);
4276
4277   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
4278      _mesa_debug(ctx, "glCopyTexImage%uD %s %d %s %d %d %d %d %d\n",
4279                  dims,
4280                  _mesa_enum_to_string(target), level,
4281                  _mesa_enum_to_string(internalFormat),
4282                  x, y, width, height, border);
4283
4284   _mesa_update_pixel(ctx);
4285
4286   if (ctx->NewState & _NEW_BUFFERS)
4287      _mesa_update_state(ctx);
4288
4289   /* check target */
4290   if (!no_error && !legal_texsubimage_target(ctx, dims, target, false)) {
4291      _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)",
4292                  dims, _mesa_enum_to_string(target));
4293      return;
4294   }
4295
4296   if (!texObj)
4297      texObj = _mesa_get_current_tex_object(ctx, target);
4298
4299   if (!no_error) {
4300      if (copytexture_error_check(ctx, dims, target, texObj, level,
4301                                  internalFormat, border))
4302         return;
4303
4304      if (!_mesa_legal_texture_dimensions(ctx, target, level, width, height,
4305                                          1, border)) {
4306         _mesa_error(ctx, GL_INVALID_VALUE,
4307                     "glCopyTexImage%uD(invalid width=%d or height=%d)",
4308                     dims, width, height);
4309         return;
4310      }
4311   }
4312
4313   assert(texObj);
4314
4315   texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
4316                                           internalFormat, GL_NONE, GL_NONE);
4317
4318   /* First check if reallocating the texture buffer can be avoided.
4319    * Without the realloc the copy can be 20x faster.
4320    */
4321   _mesa_lock_texture(ctx, texObj);
4322   {
4323      texImage = _mesa_select_tex_image(texObj, target, level);
4324      if (texImage && can_avoid_reallocation(texImage, internalFormat, texFormat,
4325                                             width, height, border)) {
4326         _mesa_unlock_texture(ctx, texObj);
4327         if (no_error) {
4328            copy_texture_sub_image_no_error(ctx, dims, texObj, target, level, 0,
4329                                            0, 0, x, y, width, height);
4330         } else {
4331            copy_texture_sub_image_err(ctx, dims, texObj, target, level, 0, 0,
4332                                       0, x, y, width, height,"CopyTexImage");
4333         }
4334         return;
4335      }
4336   }
4337   _mesa_unlock_texture(ctx, texObj);
4338   _mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_LOW, "glCopyTexImage "
4339                    "can't avoid reallocating texture storage\n");
4340
4341   if (!no_error && _mesa_is_gles3(ctx)) {
4342      struct gl_renderbuffer *rb =
4343         _mesa_get_read_renderbuffer_for_format(ctx, internalFormat);
4344
4345      if (_mesa_is_enum_format_unsized(internalFormat)) {
4346      /* Conversion from GL_RGB10_A2 source buffer format is not allowed in
4347       * OpenGL ES 3.0. Khronos bug# 9807.
4348       */
4349         if (rb->InternalFormat == GL_RGB10_A2) {
4350               _mesa_error(ctx, GL_INVALID_OPERATION,
4351                           "glCopyTexImage%uD(Reading from GL_RGB10_A2 buffer"
4352                           " and writing to unsized internal format)", dims);
4353               return;
4354         }
4355      }
4356      /* From Page 139 of OpenGL ES 3.0 spec:
4357       *    "If internalformat is sized, the internal format of the new texel
4358       *    array is internalformat, and this is also the new texel array’s
4359       *    effective internal format. If the component sizes of internalformat
4360       *    do not exactly match the corresponding component sizes of the source
4361       *    buffer’s effective internal format, described below, an
4362       *    INVALID_OPERATION error is generated. If internalformat is unsized,
4363       *    the internal format of the new texel array is the effective internal
4364       *    format of the source buffer, and this is also the new texel array’s
4365       *    effective internal format.
4366       */
4367      else if (formats_differ_in_component_sizes (texFormat, rb->Format)) {
4368            _mesa_error(ctx, GL_INVALID_OPERATION,
4369                        "glCopyTexImage%uD(component size changed in"
4370                        " internal format)", dims);
4371            return;
4372      }
4373   }
4374
4375   assert(texFormat != MESA_FORMAT_NONE);
4376
4377   if (!st_TestProxyTexImage(ctx, proxy_target(target),
4378                             0, level, texFormat, 1,
4379                             width, height, 1)) {
4380      _mesa_error(ctx, GL_OUT_OF_MEMORY,
4381                  "glCopyTexImage%uD(image too large)", dims);
4382      return;
4383   }
4384
4385   if (border) {
4386      x += border;
4387      width -= border * 2;
4388      if (dims == 2) {
4389         y += border;
4390         height -= border * 2;
4391      }
4392      border = 0;
4393   }
4394
4395   _mesa_lock_texture(ctx, texObj);
4396   {
4397      texObj->External = GL_FALSE;
4398      texImage = _mesa_get_tex_image(ctx, texObj, target, level);
4399
4400      if (!texImage) {
4401         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
4402      }
4403      else {
4404         GLint srcX = x, srcY = y, dstX = 0, dstY = 0, dstZ = 0;
4405         const GLuint face = _mesa_tex_target_to_face(target);
4406
4407         /* Free old texture image */
4408         st_FreeTextureImageBuffer(ctx, texImage);
4409
4410         _mesa_init_teximage_fields(ctx, texImage, width, height, 1,
4411                                    border, internalFormat, texFormat);
4412
4413         if (width && height) {
4414            /* Allocate texture memory (no pixel data yet) */
4415            st_AllocTextureImageBuffer(ctx, texImage);
4416
4417            if (ctx->Const.NoClippingOnCopyTex ||
4418                _mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY,
4419                                           &width, &height)) {
4420               struct gl_renderbuffer *srcRb =
4421                  get_copy_tex_image_source(ctx, texImage->TexFormat);
4422
4423               copytexsubimage_by_slice(ctx, texImage, dims,
4424                                        dstX, dstY, dstZ,
4425                                        srcRb, srcX, srcY, width, height);
4426            }
4427
4428            check_gen_mipmap(ctx, target, texObj, level);
4429         }
4430
4431         _mesa_update_fbo_texture(ctx, texObj, face, level);
4432
4433         _mesa_dirty_texobj(ctx, texObj);
4434      }
4435   }
4436   _mesa_unlock_texture(ctx, texObj);
4437}
4438
4439
4440static void
4441copyteximage_err(struct gl_context *ctx, GLuint dims,
4442                 GLenum target,
4443                 GLint level, GLenum internalFormat, GLint x, GLint y,
4444                 GLsizei width, GLsizei height, GLint border)
4445{
4446   copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height,
4447                border, false);
4448}
4449
4450
4451static void
4452copyteximage_no_error(struct gl_context *ctx, GLuint dims, GLenum target,
4453                      GLint level, GLenum internalFormat, GLint x, GLint y,
4454                      GLsizei width, GLsizei height, GLint border)
4455{
4456   copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height,
4457                border, true);
4458}
4459
4460
4461void GLAPIENTRY
4462_mesa_CopyTexImage1D( GLenum target, GLint level,
4463                      GLenum internalFormat,
4464                      GLint x, GLint y,
4465                      GLsizei width, GLint border )
4466{
4467   GET_CURRENT_CONTEXT(ctx);
4468   copyteximage_err(ctx, 1, target, level, internalFormat, x, y, width, 1,
4469                    border);
4470}
4471
4472
4473void GLAPIENTRY
4474_mesa_CopyTextureImage1DEXT( GLuint texture, GLenum target, GLint level,
4475                             GLenum internalFormat,
4476                             GLint x, GLint y,
4477                             GLsizei width, GLint border )
4478{
4479   GET_CURRENT_CONTEXT(ctx);
4480   struct gl_texture_object* texObj =
4481      _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
4482                                     "glCopyTextureImage1DEXT");
4483   if (!texObj)
4484      return;
4485   copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1,
4486                border, false);
4487}
4488
4489
4490void GLAPIENTRY
4491_mesa_CopyMultiTexImage1DEXT( GLenum texunit, GLenum target, GLint level,
4492                              GLenum internalFormat,
4493                              GLint x, GLint y,
4494                              GLsizei width, GLint border )
4495{
4496   GET_CURRENT_CONTEXT(ctx);
4497   struct gl_texture_object* texObj =
4498      _mesa_get_texobj_by_target_and_texunit(ctx, target,
4499                                             texunit - GL_TEXTURE0,
4500                                             false,
4501                                             "glCopyMultiTexImage1DEXT");
4502   if (!texObj)
4503      return;
4504   copyteximage(ctx, 1, texObj, target, level, internalFormat, x, y, width, 1,
4505                border, false);
4506}
4507
4508
4509void GLAPIENTRY
4510_mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
4511                      GLint x, GLint y, GLsizei width, GLsizei height,
4512                      GLint border )
4513{
4514   GET_CURRENT_CONTEXT(ctx);
4515   copyteximage_err(ctx, 2, target, level, internalFormat,
4516                    x, y, width, height, border);
4517}
4518
4519
4520void GLAPIENTRY
4521_mesa_CopyTextureImage2DEXT( GLuint texture, GLenum target, GLint level,
4522                             GLenum internalFormat,
4523                             GLint x, GLint y,
4524                             GLsizei width, GLsizei height,
4525                             GLint border )
4526{
4527   GET_CURRENT_CONTEXT(ctx);
4528   struct gl_texture_object* texObj =
4529      _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
4530                                     "glCopyTextureImage2DEXT");
4531   if (!texObj)
4532      return;
4533   copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height,
4534                border, false);
4535}
4536
4537
4538void GLAPIENTRY
4539_mesa_CopyMultiTexImage2DEXT( GLenum texunit, GLenum target, GLint level,
4540                              GLenum internalFormat,
4541                              GLint x, GLint y,
4542                              GLsizei width, GLsizei height, GLint border )
4543{
4544   GET_CURRENT_CONTEXT(ctx);
4545   struct gl_texture_object* texObj =
4546      _mesa_get_texobj_by_target_and_texunit(ctx, target,
4547                                             texunit - GL_TEXTURE0,
4548                                             false,
4549                                             "glCopyMultiTexImage2DEXT");
4550   if (!texObj)
4551      return;
4552   copyteximage(ctx, 2, texObj, target, level, internalFormat, x, y, width, height,
4553                border, false);
4554}
4555
4556
4557void GLAPIENTRY
4558_mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalFormat,
4559                              GLint x, GLint y, GLsizei width, GLint border)
4560{
4561   GET_CURRENT_CONTEXT(ctx);
4562   copyteximage_no_error(ctx, 1, target, level, internalFormat, x, y, width, 1,
4563                         border);
4564}
4565
4566
4567void GLAPIENTRY
4568_mesa_CopyTexImage2D_no_error(GLenum target, GLint level, GLenum internalFormat,
4569                              GLint x, GLint y, GLsizei width, GLsizei height,
4570                              GLint border)
4571{
4572   GET_CURRENT_CONTEXT(ctx);
4573   copyteximage_no_error(ctx, 2, target, level, internalFormat,
4574                         x, y, width, height, border);
4575}
4576
4577
4578void GLAPIENTRY
4579_mesa_CopyTexSubImage1D(GLenum target, GLint level,
4580                        GLint xoffset, GLint x, GLint y, GLsizei width)
4581{
4582   struct gl_texture_object* texObj;
4583   const char *self = "glCopyTexSubImage1D";
4584   GET_CURRENT_CONTEXT(ctx);
4585
4586   /* Check target (proxies not allowed). Target must be checked prior to
4587    * calling _mesa_get_current_tex_object.
4588    */
4589   if (!legal_texsubimage_target(ctx, 1, target, false)) {
4590      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
4591                  _mesa_enum_to_string(target));
4592      return;
4593   }
4594
4595   texObj = _mesa_get_current_tex_object(ctx, target);
4596   if (!texObj)
4597      return;
4598
4599   copy_texture_sub_image_err(ctx, 1, texObj, target, level, xoffset, 0, 0,
4600                              x, y, width, 1, self);
4601}
4602
4603
4604void GLAPIENTRY
4605_mesa_CopyTexSubImage2D(GLenum target, GLint level,
4606                        GLint xoffset, GLint yoffset,
4607                        GLint x, GLint y, GLsizei width, GLsizei height)
4608{
4609   struct gl_texture_object* texObj;
4610   const char *self = "glCopyTexSubImage2D";
4611   GET_CURRENT_CONTEXT(ctx);
4612
4613   /* Check target (proxies not allowed). Target must be checked prior to
4614    * calling _mesa_get_current_tex_object.
4615    */
4616   if (!legal_texsubimage_target(ctx, 2, target, false)) {
4617      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
4618                  _mesa_enum_to_string(target));
4619      return;
4620   }
4621
4622   texObj = _mesa_get_current_tex_object(ctx, target);
4623   if (!texObj)
4624      return;
4625
4626   copy_texture_sub_image_err(ctx, 2, texObj, target, level, xoffset, yoffset,
4627                              0, x, y, width, height, self);
4628}
4629
4630
4631void GLAPIENTRY
4632_mesa_CopyTexSubImage3D(GLenum target, GLint level,
4633                        GLint xoffset, GLint yoffset, GLint zoffset,
4634                        GLint x, GLint y, GLsizei width, GLsizei height)
4635{
4636   struct gl_texture_object* texObj;
4637   const char *self = "glCopyTexSubImage3D";
4638   GET_CURRENT_CONTEXT(ctx);
4639
4640   /* Check target (proxies not allowed). Target must be checked prior to
4641    * calling _mesa_get_current_tex_object.
4642    */
4643   if (!legal_texsubimage_target(ctx, 3, target, false)) {
4644      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", self,
4645                  _mesa_enum_to_string(target));
4646      return;
4647   }
4648
4649   texObj = _mesa_get_current_tex_object(ctx, target);
4650   if (!texObj)
4651      return;
4652
4653   copy_texture_sub_image_err(ctx, 3, texObj, target, level, xoffset, yoffset,
4654                              zoffset, x, y, width, height, self);
4655}
4656
4657
4658void GLAPIENTRY
4659_mesa_CopyTextureSubImage1D(GLuint texture, GLint level,
4660                            GLint xoffset, GLint x, GLint y, GLsizei width)
4661{
4662   struct gl_texture_object* texObj;
4663   const char *self = "glCopyTextureSubImage1D";
4664   GET_CURRENT_CONTEXT(ctx);
4665
4666   texObj = _mesa_lookup_texture_err(ctx, texture, self);
4667   if (!texObj)
4668      return;
4669
4670   /* Check target (proxies not allowed). */
4671   if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) {
4672      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
4673                  _mesa_enum_to_string(texObj->Target));
4674      return;
4675   }
4676
4677   copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0,
4678                              0, x, y, width, 1, self);
4679}
4680
4681
4682void GLAPIENTRY
4683_mesa_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level,
4684                               GLint xoffset, GLint x, GLint y, GLsizei width)
4685{
4686   struct gl_texture_object* texObj;
4687   const char *self = "glCopyTextureSubImage1DEXT";
4688   GET_CURRENT_CONTEXT(ctx);
4689
4690   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
4691                                           self);
4692   if (!texObj)
4693      return;
4694
4695   /* Check target (proxies not allowed). */
4696   if (!legal_texsubimage_target(ctx, 1, texObj->Target, true)) {
4697      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
4698                  _mesa_enum_to_string(texObj->Target));
4699      return;
4700   }
4701
4702   copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0,
4703                              0, x, y, width, 1, self);
4704}
4705
4706
4707void GLAPIENTRY
4708_mesa_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level,
4709                                GLint xoffset, GLint x, GLint y, GLsizei width)
4710{
4711   struct gl_texture_object* texObj;
4712   const char *self = "glCopyMultiTexSubImage1DEXT";
4713   GET_CURRENT_CONTEXT(ctx);
4714
4715   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
4716                                                   texunit - GL_TEXTURE0,
4717                                                   false, self);
4718   if (!texObj)
4719      return;
4720
4721   copy_texture_sub_image_err(ctx, 1, texObj, texObj->Target, level, xoffset, 0,
4722                              0, x, y, width, 1, self);
4723}
4724
4725
4726void GLAPIENTRY
4727_mesa_CopyTextureSubImage2D(GLuint texture, GLint level,
4728                            GLint xoffset, GLint yoffset,
4729                            GLint x, GLint y, GLsizei width, GLsizei height)
4730{
4731   struct gl_texture_object* texObj;
4732   const char *self = "glCopyTextureSubImage2D";
4733   GET_CURRENT_CONTEXT(ctx);
4734
4735   texObj = _mesa_lookup_texture_err(ctx, texture, self);
4736   if (!texObj)
4737      return;
4738
4739   /* Check target (proxies not allowed). */
4740   if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) {
4741      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
4742                  _mesa_enum_to_string(texObj->Target));
4743      return;
4744   }
4745
4746   copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset,
4747                              yoffset, 0, x, y, width, height, self);
4748}
4749
4750
4751void GLAPIENTRY
4752_mesa_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level,
4753                               GLint xoffset, GLint yoffset,
4754                               GLint x, GLint y, GLsizei width, GLsizei height)
4755{
4756   struct gl_texture_object* texObj;
4757   const char *self = "glCopyTextureSubImage2DEXT";
4758   GET_CURRENT_CONTEXT(ctx);
4759
4760   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self);
4761   if (!texObj)
4762      return;
4763
4764   /* Check target (proxies not allowed). */
4765   if (!legal_texsubimage_target(ctx, 2, texObj->Target, true)) {
4766      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
4767                  _mesa_enum_to_string(texObj->Target));
4768      return;
4769   }
4770
4771   copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset,
4772                              yoffset, 0, x, y, width, height, self);
4773}
4774
4775
4776void GLAPIENTRY
4777_mesa_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level,
4778                               GLint xoffset, GLint yoffset,
4779                               GLint x, GLint y, GLsizei width, GLsizei height)
4780{
4781   struct gl_texture_object* texObj;
4782   const char *self = "glCopyMultiTexSubImage2DEXT";
4783   GET_CURRENT_CONTEXT(ctx);
4784
4785   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
4786                                                   texunit - GL_TEXTURE0,
4787                                                   false, self);
4788   if (!texObj)
4789      return;
4790
4791   copy_texture_sub_image_err(ctx, 2, texObj, texObj->Target, level, xoffset,
4792                              yoffset, 0, x, y, width, height, self);
4793}
4794
4795void GLAPIENTRY
4796_mesa_CopyTextureSubImage3D(GLuint texture, GLint level,
4797                            GLint xoffset, GLint yoffset, GLint zoffset,
4798                            GLint x, GLint y, GLsizei width, GLsizei height)
4799{
4800   struct gl_texture_object* texObj;
4801   const char *self = "glCopyTextureSubImage3D";
4802   GET_CURRENT_CONTEXT(ctx);
4803
4804   texObj = _mesa_lookup_texture_err(ctx, texture, self);
4805   if (!texObj)
4806      return;
4807
4808   /* Check target (proxies not allowed). */
4809   if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) {
4810      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
4811                  _mesa_enum_to_string(texObj->Target));
4812      return;
4813   }
4814
4815   if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
4816      /* Act like CopyTexSubImage2D */
4817      copy_texture_sub_image_err(ctx, 2, texObj,
4818                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
4819                                level, xoffset, yoffset, 0, x, y, width, height,
4820                                self);
4821   }
4822   else
4823      copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset,
4824                                 yoffset, zoffset, x, y, width, height, self);
4825}
4826
4827
4828void GLAPIENTRY
4829_mesa_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level,
4830                               GLint xoffset, GLint yoffset, GLint zoffset,
4831                               GLint x, GLint y, GLsizei width, GLsizei height)
4832{
4833   struct gl_texture_object* texObj;
4834   const char *self = "glCopyTextureSubImage3D";
4835   GET_CURRENT_CONTEXT(ctx);
4836
4837   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true, self);
4838   if (!texObj)
4839      return;
4840
4841   /* Check target (proxies not allowed). */
4842   if (!legal_texsubimage_target(ctx, 3, texObj->Target, true)) {
4843      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", self,
4844                  _mesa_enum_to_string(texObj->Target));
4845      return;
4846   }
4847
4848   if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
4849      /* Act like CopyTexSubImage2D */
4850      copy_texture_sub_image_err(ctx, 2, texObj,
4851                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
4852                                level, xoffset, yoffset, 0, x, y, width, height,
4853                                self);
4854   }
4855   else
4856      copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset,
4857                                 yoffset, zoffset, x, y, width, height, self);
4858}
4859
4860
4861void GLAPIENTRY
4862_mesa_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level,
4863                                GLint xoffset, GLint yoffset, GLint zoffset,
4864                                GLint x, GLint y, GLsizei width, GLsizei height)
4865{
4866   struct gl_texture_object* texObj;
4867   const char *self = "glCopyMultiTexSubImage3D";
4868   GET_CURRENT_CONTEXT(ctx);
4869
4870   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
4871                                                   texunit - GL_TEXTURE0,
4872                                                   false, self);
4873   if (!texObj)
4874      return;
4875
4876   if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
4877      /* Act like CopyTexSubImage2D */
4878      copy_texture_sub_image_err(ctx, 2, texObj,
4879                                GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
4880                                level, xoffset, yoffset, 0, x, y, width, height,
4881                                self);
4882   }
4883   else
4884      copy_texture_sub_image_err(ctx, 3, texObj, texObj->Target, level, xoffset,
4885                                 yoffset, zoffset, x, y, width, height, self);
4886}
4887
4888
4889void GLAPIENTRY
4890_mesa_CopyTexSubImage1D_no_error(GLenum target, GLint level, GLint xoffset,
4891                                 GLint x, GLint y, GLsizei width)
4892{
4893   GET_CURRENT_CONTEXT(ctx);
4894
4895   struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
4896   copy_texture_sub_image_no_error(ctx, 1, texObj, target, level, xoffset, 0, 0,
4897                                   x, y, width, 1);
4898}
4899
4900
4901void GLAPIENTRY
4902_mesa_CopyTexSubImage2D_no_error(GLenum target, GLint level, GLint xoffset,
4903                                 GLint yoffset, GLint x, GLint y, GLsizei width,
4904                                 GLsizei height)
4905{
4906   GET_CURRENT_CONTEXT(ctx);
4907
4908   struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
4909   copy_texture_sub_image_no_error(ctx, 2, texObj, target, level, xoffset,
4910                                   yoffset, 0, x, y, width, height);
4911}
4912
4913
4914void GLAPIENTRY
4915_mesa_CopyTexSubImage3D_no_error(GLenum target, GLint level, GLint xoffset,
4916                                 GLint yoffset, GLint zoffset, GLint x, GLint y,
4917                                 GLsizei width, GLsizei height)
4918{
4919   GET_CURRENT_CONTEXT(ctx);
4920
4921   struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target);
4922   copy_texture_sub_image_no_error(ctx, 3, texObj, target, level, xoffset,
4923                                   yoffset, zoffset, x, y, width, height);
4924}
4925
4926
4927void GLAPIENTRY
4928_mesa_CopyTextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset,
4929                                     GLint x, GLint y, GLsizei width)
4930{
4931   GET_CURRENT_CONTEXT(ctx);
4932
4933   struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
4934   copy_texture_sub_image_no_error(ctx, 1, texObj, texObj->Target, level,
4935                                   xoffset, 0, 0, x, y, width, 1);
4936}
4937
4938
4939void GLAPIENTRY
4940_mesa_CopyTextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset,
4941                                     GLint yoffset, GLint x, GLint y,
4942                                     GLsizei width, GLsizei height)
4943{
4944   GET_CURRENT_CONTEXT(ctx);
4945
4946   struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
4947   copy_texture_sub_image_no_error(ctx, 2, texObj, texObj->Target, level,
4948                                   xoffset, yoffset, 0, x, y, width, height);
4949}
4950
4951
4952void GLAPIENTRY
4953_mesa_CopyTextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset,
4954                                     GLint yoffset, GLint zoffset, GLint x,
4955                                     GLint y, GLsizei width, GLsizei height)
4956{
4957   GET_CURRENT_CONTEXT(ctx);
4958
4959   struct gl_texture_object* texObj = _mesa_lookup_texture(ctx, texture);
4960   if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
4961      /* Act like CopyTexSubImage2D */
4962      copy_texture_sub_image_no_error(ctx, 2, texObj,
4963                                      GL_TEXTURE_CUBE_MAP_POSITIVE_X + zoffset,
4964                                      level, xoffset, yoffset, 0, x, y, width,
4965                                      height);
4966   }
4967   else
4968      copy_texture_sub_image_no_error(ctx, 3, texObj, texObj->Target, level,
4969                                      xoffset, yoffset, zoffset, x, y, width,
4970                                      height);
4971}
4972
4973
4974static bool
4975check_clear_tex_image(struct gl_context *ctx,
4976                      const char *function,
4977                      struct gl_texture_image *texImage,
4978                      GLenum format, GLenum type,
4979                      const void *data,
4980                      GLubyte *clearValue)
4981{
4982   struct gl_texture_object *texObj = texImage->TexObject;
4983   static const GLubyte zeroData[MAX_PIXEL_BYTES];
4984   GLenum internalFormat = texImage->InternalFormat;
4985   GLenum err;
4986
4987   if (texObj->Target == GL_TEXTURE_BUFFER) {
4988      _mesa_error(ctx, GL_INVALID_OPERATION,
4989                  "%s(buffer texture)", function);
4990      return false;
4991   }
4992
4993   if (_mesa_is_compressed_format(ctx, internalFormat)) {
4994      _mesa_error(ctx, GL_INVALID_OPERATION,
4995                  "%s(compressed texture)", function);
4996      return false;
4997   }
4998
4999   err = _mesa_error_check_format_and_type(ctx, format, type);
5000   if (err != GL_NO_ERROR) {
5001      _mesa_error(ctx, err,
5002                  "%s(incompatible format = %s, type = %s)",
5003                  function,
5004                  _mesa_enum_to_string(format),
5005                  _mesa_enum_to_string(type));
5006      return false;
5007   }
5008
5009   /* make sure internal format and format basically agree */
5010   if (!texture_formats_agree(internalFormat, format)) {
5011      _mesa_error(ctx, GL_INVALID_OPERATION,
5012                  "%s(incompatible internalFormat = %s, format = %s)",
5013                  function,
5014                  _mesa_enum_to_string(internalFormat),
5015                  _mesa_enum_to_string(format));
5016      return false;
5017   }
5018
5019   if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) {
5020      /* both source and dest must be integer-valued, or neither */
5021      if (_mesa_is_format_integer_color(texImage->TexFormat) !=
5022          _mesa_is_enum_format_integer(format)) {
5023         _mesa_error(ctx, GL_INVALID_OPERATION,
5024                     "%s(integer/non-integer format mismatch)",
5025                     function);
5026         return false;
5027      }
5028   }
5029
5030   if (!_mesa_texstore(ctx,
5031                       1, /* dims */
5032                       texImage->_BaseFormat,
5033                       texImage->TexFormat,
5034                       0, /* dstRowStride */
5035                       &clearValue,
5036                       1, 1, 1, /* srcWidth/Height/Depth */
5037                       format, type,
5038                       data ? data : zeroData,
5039                       &ctx->DefaultPacking)) {
5040      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid format)", function);
5041      return false;
5042   }
5043
5044   return true;
5045}
5046
5047
5048static struct gl_texture_object *
5049get_tex_obj_for_clear(struct gl_context *ctx,
5050                      const char *function,
5051                      GLuint texture)
5052{
5053   struct gl_texture_object *texObj;
5054
5055   texObj = _mesa_lookup_texture_err(ctx, texture, function);
5056   if (!texObj)
5057      return NULL;
5058
5059   if (texObj->Target == 0) {
5060      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unbound tex)", function);
5061      return NULL;
5062   }
5063
5064   return texObj;
5065}
5066
5067
5068/**
5069 * For clearing cube textures, the zoffset and depth parameters indicate
5070 * which cube map faces are to be cleared.  This is the one case where we
5071 * need to be concerned with multiple gl_texture_images.  This function
5072 * returns the array of texture images to clear for cube maps, or one
5073 * texture image otherwise.
5074 * \return number of texture images, 0 for error, 6 for cube, 1 otherwise.
5075 */
5076static int
5077get_tex_images_for_clear(struct gl_context *ctx,
5078                         const char *function,
5079                         struct gl_texture_object *texObj,
5080                         GLint level,
5081                         struct gl_texture_image **texImages)
5082{
5083   GLenum target;
5084   int numFaces, i;
5085
5086   if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
5087      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
5088      return 0;
5089   }
5090
5091   if (texObj->Target == GL_TEXTURE_CUBE_MAP) {
5092      target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
5093      numFaces = MAX_FACES;
5094   }
5095   else {
5096      target = texObj->Target;
5097      numFaces = 1;
5098   }
5099
5100   for (i = 0; i < numFaces; i++) {
5101      texImages[i] = _mesa_select_tex_image(texObj, target + i, level);
5102      if (texImages[i] == NULL) {
5103         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid level)", function);
5104         return 0;
5105      }
5106   }
5107
5108   return numFaces;
5109}
5110
5111
5112void GLAPIENTRY
5113_mesa_ClearTexSubImage(GLuint texture, GLint level,
5114                       GLint xoffset, GLint yoffset, GLint zoffset,
5115                       GLsizei width, GLsizei height, GLsizei depth,
5116                       GLenum format, GLenum type, const void *data)
5117{
5118   GET_CURRENT_CONTEXT(ctx);
5119   struct gl_texture_object *texObj;
5120   struct gl_texture_image *texImages[MAX_FACES];
5121   GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES];
5122   int i, numImages;
5123   int minDepth, maxDepth;
5124
5125   texObj = get_tex_obj_for_clear(ctx, "glClearTexSubImage", texture);
5126
5127   if (texObj == NULL)
5128      return;
5129
5130   _mesa_lock_texture(ctx, texObj);
5131
5132   numImages = get_tex_images_for_clear(ctx, "glClearTexSubImage",
5133                                        texObj, level, texImages);
5134   if (numImages == 0)
5135      goto out;
5136
5137   if (numImages == 1) {
5138      minDepth = -(int) texImages[0]->Border;
5139      maxDepth = texImages[0]->Depth;
5140   } else {
5141      assert(numImages == MAX_FACES);
5142      minDepth = 0;
5143      maxDepth = numImages;
5144   }
5145
5146   if (xoffset < -(GLint) texImages[0]->Border ||
5147       yoffset < -(GLint) texImages[0]->Border ||
5148       zoffset < minDepth ||
5149       width < 0 ||
5150       height < 0 ||
5151       depth < 0 ||
5152       xoffset + width > texImages[0]->Width ||
5153       yoffset + height > texImages[0]->Height ||
5154       zoffset + depth > maxDepth) {
5155      _mesa_error(ctx, GL_INVALID_OPERATION,
5156                  "glClearSubTexImage(invalid dimensions)");
5157      goto out;
5158   }
5159
5160   if (numImages == 1) {
5161      if (check_clear_tex_image(ctx, "glClearTexSubImage", texImages[0],
5162                                format, type, data, clearValue[0])) {
5163         st_ClearTexSubImage(ctx,
5164                             texImages[0],
5165                             xoffset, yoffset, zoffset,
5166                             width, height, depth,
5167                             data ? clearValue[0] : NULL);
5168      }
5169   } else {
5170      /* loop over cube face images */
5171      for (i = zoffset; i < zoffset + depth; i++) {
5172         assert(i < MAX_FACES);
5173         if (!check_clear_tex_image(ctx, "glClearTexSubImage", texImages[i],
5174                                    format, type, data, clearValue[i]))
5175            goto out;
5176      }
5177      for (i = zoffset; i < zoffset + depth; i++) {
5178         st_ClearTexSubImage(ctx,
5179                             texImages[i],
5180                             xoffset, yoffset, 0,
5181                             width, height, 1,
5182                             data ? clearValue[i] : NULL);
5183      }
5184   }
5185
5186 out:
5187   _mesa_unlock_texture(ctx, texObj);
5188}
5189
5190
5191void GLAPIENTRY
5192_mesa_ClearTexImage( GLuint texture, GLint level,
5193                     GLenum format, GLenum type, const void *data )
5194{
5195   GET_CURRENT_CONTEXT(ctx);
5196   struct gl_texture_object *texObj;
5197   struct gl_texture_image *texImages[MAX_FACES];
5198   GLubyte clearValue[MAX_FACES][MAX_PIXEL_BYTES];
5199   int i, numImages;
5200
5201   texObj = get_tex_obj_for_clear(ctx, "glClearTexImage", texture);
5202
5203   if (texObj == NULL)
5204      return;
5205
5206   _mesa_lock_texture(ctx, texObj);
5207
5208   numImages = get_tex_images_for_clear(ctx, "glClearTexImage",
5209                                        texObj, level, texImages);
5210
5211   for (i = 0; i < numImages; i++) {
5212      if (!check_clear_tex_image(ctx, "glClearTexImage", texImages[i], format,
5213                                 type, data, clearValue[i]))
5214         goto out;
5215   }
5216
5217   for (i = 0; i < numImages; i++) {
5218      st_ClearTexSubImage(ctx, texImages[i],
5219                          -(GLint) texImages[i]->Border, /* xoffset */
5220                          -(GLint) texImages[i]->Border, /* yoffset */
5221                          -(GLint) texImages[i]->Border, /* zoffset */
5222                          texImages[i]->Width,
5223                          texImages[i]->Height,
5224                          texImages[i]->Depth,
5225                          data ? clearValue[i] : NULL);
5226   }
5227
5228out:
5229   _mesa_unlock_texture(ctx, texObj);
5230}
5231
5232
5233
5234
5235/**********************************************************************/
5236/******                   Compressed Textures                    ******/
5237/**********************************************************************/
5238
5239
5240/**
5241 * Target checking for glCompressedTexSubImage[123]D().
5242 * \return GL_TRUE if error, GL_FALSE if no error
5243 * Must come before other error checking so that the texture object can
5244 * be correctly retrieved using _mesa_get_current_tex_object.
5245 */
5246static GLboolean
5247compressed_subtexture_target_check(struct gl_context *ctx, GLenum target,
5248                                   GLint dims, GLenum intFormat, bool dsa,
5249                                   const char *caller)
5250{
5251   GLboolean targetOK;
5252   mesa_format format;
5253   enum mesa_format_layout layout;
5254
5255   if (dsa && target == GL_TEXTURE_RECTANGLE) {
5256      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid target %s)", caller,
5257                  _mesa_enum_to_string(target));
5258      return GL_TRUE;
5259   }
5260
5261   switch (dims) {
5262   case 2:
5263      switch (target) {
5264      case GL_TEXTURE_2D:
5265         targetOK = GL_TRUE;
5266         break;
5267      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5268      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5269      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5270      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5271      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5272      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5273         targetOK = GL_TRUE;
5274         break;
5275      default:
5276         targetOK = GL_FALSE;
5277         break;
5278      }
5279      break;
5280   case 3:
5281      switch (target) {
5282      case GL_TEXTURE_CUBE_MAP:
5283         targetOK = dsa;
5284         break;
5285      case GL_TEXTURE_2D_ARRAY:
5286         targetOK = _mesa_is_gles3(ctx) ||
5287            (_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_array);
5288         break;
5289      case GL_TEXTURE_CUBE_MAP_ARRAY:
5290         targetOK = _mesa_has_texture_cube_map_array(ctx);
5291         break;
5292      case GL_TEXTURE_3D:
5293         targetOK = GL_TRUE;
5294         /*
5295          * OpenGL 4.5 spec (30.10.2014) says in Section 8.7 Compressed Texture
5296          * Images:
5297          *    "An INVALID_OPERATION error is generated by
5298          *    CompressedTex*SubImage3D if the internal format of the texture
5299          *    is one of the EAC, ETC2, or RGTC formats and either border is
5300          *    non-zero, or the effective target for the texture is not
5301          *    TEXTURE_2D_ARRAY."
5302          *
5303          * NOTE: that's probably a spec error.  It should probably say
5304          *    "... or the effective target for the texture is not
5305          *    TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP, nor
5306          *    GL_TEXTURE_CUBE_MAP_ARRAY."
5307          * since those targets are 2D images and they support all compression
5308          * formats.
5309          *
5310          * Instead of listing all these, just list those which are allowed,
5311          * which is (at this time) only bptc. Otherwise we'd say s3tc (and
5312          * more) are valid here, which they are not, but of course not
5313          * mentioned by core spec.
5314          *
5315          * Also, from GL_KHR_texture_compression_astc_{hdr,ldr}:
5316          *
5317          *    "Add a second new column "3D Tex." which is empty for all non-ASTC
5318          *     formats. If only the LDR profile is supported by the implementation,
5319          *     this column is also empty for all ASTC formats. If both the LDR and HDR
5320          *     profiles are supported, this column is checked for all ASTC formats."
5321          *
5322          *    "An INVALID_OPERATION error is generated by CompressedTexSubImage3D if
5323          *     <format> is one of the formats in table 8.19 and <target> is not
5324          *     TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, or TEXTURE_3D.
5325          *
5326          *     An INVALID_OPERATION error is generated by CompressedTexSubImage3D if
5327          *     <format> is TEXTURE_CUBE_MAP_ARRAY and the "Cube Map Array" column of
5328          *     table 8.19 is *not* checked, or if <format> is TEXTURE_3D and the "3D
5329          *     Tex." column of table 8.19 is *not* checked"
5330          *
5331          * And from GL_KHR_texture_compression_astc_sliced_3d:
5332          *
5333          *    "Modify the "3D Tex." column to be checked for all ASTC formats."
5334          */
5335         format = _mesa_glenum_to_compressed_format(intFormat);
5336         layout = _mesa_get_format_layout(format);
5337         switch (layout) {
5338         case MESA_FORMAT_LAYOUT_BPTC:
5339            /* valid format */
5340            break;
5341         case MESA_FORMAT_LAYOUT_ASTC:
5342            targetOK =
5343               ctx->Extensions.KHR_texture_compression_astc_hdr ||
5344               ctx->Extensions.KHR_texture_compression_astc_sliced_3d;
5345            break;
5346         default:
5347            /* invalid format */
5348            _mesa_error(ctx, GL_INVALID_OPERATION,
5349                        "%s(invalid target %s for format %s)", caller,
5350                        _mesa_enum_to_string(target),
5351                        _mesa_enum_to_string(intFormat));
5352            return GL_TRUE;
5353         }
5354         break;
5355      default:
5356         targetOK = GL_FALSE;
5357      }
5358
5359      break;
5360   default:
5361      assert(dims == 1);
5362      /* no 1D compressed textures at this time */
5363      targetOK = GL_FALSE;
5364      break;
5365   }
5366
5367   if (!targetOK) {
5368      _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid target %s)", caller,
5369                  _mesa_enum_to_string(target));
5370      return GL_TRUE;
5371   }
5372
5373   return GL_FALSE;
5374}
5375
5376/**
5377 * Error checking for glCompressedTexSubImage[123]D().
5378 * \return GL_TRUE if error, GL_FALSE if no error
5379 */
5380static GLboolean
5381compressed_subtexture_error_check(struct gl_context *ctx, GLint dims,
5382                                  const struct gl_texture_object *texObj,
5383                                  GLenum target, GLint level,
5384                                  GLint xoffset, GLint yoffset, GLint zoffset,
5385                                  GLsizei width, GLsizei height, GLsizei depth,
5386                                  GLenum format, GLsizei imageSize,
5387                                  const GLvoid *data, const char *callerName)
5388{
5389   struct gl_texture_image *texImage;
5390   GLint expectedSize;
5391
5392   GLenum is_generic_compressed_token =
5393      _mesa_generic_compressed_format_to_uncompressed_format(format) !=
5394      format;
5395
5396   /* OpenGL 4.6 and OpenGL ES 3.2 spec:
5397    *
5398    *   "An INVALID_OPERATION error is generated if format does not match the
5399    *    internal format of the texture image being modified, since these commands do
5400    *    not provide for image format conversion."
5401    *
5402    *  Desktop spec has an additional rule for GL_INVALID_ENUM:
5403    *
5404    *   "An INVALID_ENUM error is generated if format is one of the generic
5405    *    compressed internal formats."
5406    */
5407   /* this will catch any invalid compressed format token */
5408   if (!_mesa_is_compressed_format(ctx, format)) {
5409      GLenum error = _mesa_is_desktop_gl(ctx) && is_generic_compressed_token ?
5410         GL_INVALID_ENUM : GL_INVALID_OPERATION;
5411      _mesa_error(ctx, error, "%s(format)", callerName);
5412      return GL_TRUE;
5413   }
5414
5415   if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) {
5416      _mesa_error(ctx, GL_INVALID_VALUE, "%s(level=%d)", callerName, level);
5417      return GL_TRUE;
5418   }
5419
5420   /* validate the bound PBO, if any */
5421   if (!_mesa_validate_pbo_source_compressed(ctx, dims, &ctx->Unpack,
5422                                     imageSize, data, callerName)) {
5423      return GL_TRUE;
5424   }
5425
5426   /* Check for invalid pixel storage modes */
5427   if (!_mesa_compressed_pixel_storage_error_check(ctx, dims,
5428                                                   &ctx->Unpack, callerName)) {
5429      return GL_TRUE;
5430   }
5431
5432   expectedSize = compressed_tex_size(width, height, depth, format);
5433   if (expectedSize != imageSize) {
5434      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", callerName, imageSize);
5435      return GL_TRUE;
5436   }
5437
5438   texImage = _mesa_select_tex_image(texObj, target, level);
5439   if (!texImage) {
5440      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid texture level %d)",
5441                  callerName, level);
5442      return GL_TRUE;
5443   }
5444
5445   if ((GLint) format != texImage->InternalFormat) {
5446      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s)",
5447                  callerName, _mesa_enum_to_string(format));
5448      return GL_TRUE;
5449   }
5450
5451   if (compressedteximage_only_format(format)) {
5452      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(format=%s cannot be updated)",
5453                  callerName, _mesa_enum_to_string(format));
5454      return GL_TRUE;
5455   }
5456
5457   if (error_check_subtexture_negative_dimensions(ctx, dims, width, height,
5458                                                  depth, callerName)) {
5459      return GL_TRUE;
5460   }
5461
5462   if (error_check_subtexture_dimensions(ctx, dims, texImage, xoffset, yoffset,
5463                                         zoffset, width, height, depth,
5464                                         callerName)) {
5465      return GL_TRUE;
5466   }
5467
5468   return GL_FALSE;
5469}
5470
5471
5472void GLAPIENTRY
5473_mesa_CompressedTexImage1D(GLenum target, GLint level,
5474                              GLenum internalFormat, GLsizei width,
5475                              GLint border, GLsizei imageSize,
5476                              const GLvoid *data)
5477{
5478   GET_CURRENT_CONTEXT(ctx);
5479   teximage_err(ctx, GL_TRUE, 1, target, level, internalFormat,
5480                width, 1, 1, border, GL_NONE, GL_NONE, imageSize, data);
5481}
5482
5483
5484void GLAPIENTRY
5485_mesa_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level,
5486                                  GLenum internalFormat, GLsizei width,
5487                                  GLint border, GLsizei imageSize,
5488                                  const GLvoid *pixels)
5489{
5490   struct gl_texture_object*  texObj;
5491   GET_CURRENT_CONTEXT(ctx);
5492
5493   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
5494                                           "glCompressedTextureImage1DEXT");
5495   if (!texObj)
5496      return;
5497   teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat,
5498            width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5499}
5500
5501
5502void GLAPIENTRY
5503_mesa_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level,
5504                                   GLenum internalFormat, GLsizei width,
5505                                   GLint border, GLsizei imageSize,
5506                                   const GLvoid *pixels)
5507{
5508   struct gl_texture_object*  texObj;
5509   GET_CURRENT_CONTEXT(ctx);
5510
5511   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5512                                                   texunit - GL_TEXTURE0,
5513                                                   true,
5514                                                   "glCompressedMultiTexImage1DEXT");
5515   if (!texObj)
5516      return;
5517   teximage(ctx, GL_TRUE, 1, texObj, target, level, internalFormat,
5518            width, 1, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5519}
5520
5521
5522void GLAPIENTRY
5523_mesa_CompressedTexImage2D(GLenum target, GLint level,
5524                              GLenum internalFormat, GLsizei width,
5525                              GLsizei height, GLint border, GLsizei imageSize,
5526                              const GLvoid *data)
5527{
5528   GET_CURRENT_CONTEXT(ctx);
5529   teximage_err(ctx, GL_TRUE, 2, target, level, internalFormat,
5530                width, height, 1, border, GL_NONE, GL_NONE, imageSize, data);
5531}
5532
5533
5534void GLAPIENTRY
5535_mesa_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level,
5536                                  GLenum internalFormat, GLsizei width,
5537                                  GLsizei height, GLint border, GLsizei imageSize,
5538                                  const GLvoid *pixels)
5539{
5540   struct gl_texture_object*  texObj;
5541   GET_CURRENT_CONTEXT(ctx);
5542
5543   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
5544                                           "glCompressedTextureImage2DEXT");
5545   if (!texObj)
5546      return;
5547   teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat,
5548            width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5549}
5550
5551
5552void GLAPIENTRY
5553_mesa_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level,
5554                                   GLenum internalFormat, GLsizei width,
5555                                   GLsizei height, GLint border, GLsizei imageSize,
5556                                   const GLvoid *pixels)
5557{
5558   struct gl_texture_object*  texObj;
5559   GET_CURRENT_CONTEXT(ctx);
5560
5561   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5562                                                   texunit - GL_TEXTURE0,
5563                                                   true,
5564                                                   "glCompressedMultiTexImage2DEXT");
5565   if (!texObj)
5566      return;
5567   teximage(ctx, GL_TRUE, 2, texObj, target, level, internalFormat,
5568            width, height, 1, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5569}
5570
5571
5572void GLAPIENTRY
5573_mesa_CompressedTexImage3D(GLenum target, GLint level,
5574                              GLenum internalFormat, GLsizei width,
5575                              GLsizei height, GLsizei depth, GLint border,
5576                              GLsizei imageSize, const GLvoid *data)
5577{
5578   GET_CURRENT_CONTEXT(ctx);
5579   teximage_err(ctx, GL_TRUE, 3, target, level, internalFormat, width, height,
5580                depth, border, GL_NONE, GL_NONE, imageSize, data);
5581}
5582
5583
5584void GLAPIENTRY
5585_mesa_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level,
5586                                  GLenum internalFormat, GLsizei width,
5587                                  GLsizei height, GLsizei depth, GLint border,
5588                                  GLsizei imageSize, const GLvoid *pixels)
5589{
5590   struct gl_texture_object*  texObj;
5591   GET_CURRENT_CONTEXT(ctx);
5592
5593   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
5594                                           "glCompressedTextureImage3DEXT");
5595   if (!texObj)
5596      return;
5597   teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat,
5598            width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5599}
5600
5601
5602void GLAPIENTRY
5603_mesa_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level,
5604                                   GLenum internalFormat, GLsizei width,
5605                                   GLsizei height, GLsizei depth, GLint border,
5606                                   GLsizei imageSize, const GLvoid *pixels)
5607{
5608   struct gl_texture_object*  texObj;
5609   GET_CURRENT_CONTEXT(ctx);
5610
5611   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5612                                                   texunit - GL_TEXTURE0,
5613                                                   true,
5614                                                   "glCompressedMultiTexImage3DEXT");
5615   if (!texObj)
5616      return;
5617   teximage(ctx, GL_TRUE, 3, texObj, target, level, internalFormat,
5618            width, height, depth, border, GL_NONE, GL_NONE, imageSize, pixels, false);
5619}
5620
5621
5622void GLAPIENTRY
5623_mesa_CompressedTexImage1D_no_error(GLenum target, GLint level,
5624                                    GLenum internalFormat, GLsizei width,
5625                                    GLint border, GLsizei imageSize,
5626                                    const GLvoid *data)
5627{
5628   GET_CURRENT_CONTEXT(ctx);
5629   teximage_no_error(ctx, GL_TRUE, 1, target, level, internalFormat, width, 1,
5630                     1, border, GL_NONE, GL_NONE, imageSize, data);
5631}
5632
5633
5634void GLAPIENTRY
5635_mesa_CompressedTexImage2D_no_error(GLenum target, GLint level,
5636                                    GLenum internalFormat, GLsizei width,
5637                                    GLsizei height, GLint border,
5638                                    GLsizei imageSize, const GLvoid *data)
5639{
5640   GET_CURRENT_CONTEXT(ctx);
5641   teximage_no_error(ctx, GL_TRUE, 2, target, level, internalFormat, width,
5642                     height, 1, border, GL_NONE, GL_NONE, imageSize, data);
5643}
5644
5645
5646void GLAPIENTRY
5647_mesa_CompressedTexImage3D_no_error(GLenum target, GLint level,
5648                                    GLenum internalFormat, GLsizei width,
5649                                    GLsizei height, GLsizei depth, GLint border,
5650                                    GLsizei imageSize, const GLvoid *data)
5651{
5652   GET_CURRENT_CONTEXT(ctx);
5653   teximage_no_error(ctx, GL_TRUE, 3, target, level, internalFormat, width,
5654                     height, depth, border, GL_NONE, GL_NONE, imageSize, data);
5655}
5656
5657
5658/**
5659 * Common helper for glCompressedTexSubImage1/2/3D() and
5660 * glCompressedTextureSubImage1/2/3D().
5661 */
5662static void
5663compressed_texture_sub_image(struct gl_context *ctx, GLuint dims,
5664                             struct gl_texture_object *texObj,
5665                             struct gl_texture_image *texImage,
5666                             GLenum target, GLint level, GLint xoffset,
5667                             GLint yoffset, GLint zoffset, GLsizei width,
5668                             GLsizei height, GLsizei depth, GLenum format,
5669                             GLsizei imageSize, const GLvoid *data)
5670{
5671   FLUSH_VERTICES(ctx, 0, 0);
5672
5673   _mesa_lock_texture(ctx, texObj);
5674   {
5675      if (width > 0 && height > 0 && depth > 0) {
5676         st_CompressedTexSubImage(ctx, dims, texImage,
5677                                  xoffset, yoffset, zoffset,
5678                                  width, height, depth,
5679                                  format, imageSize, data);
5680
5681         check_gen_mipmap(ctx, target, texObj, level);
5682
5683         /* NOTE: Don't signal _NEW_TEXTURE_OBJECT since we've only changed
5684          * the texel data, not the texture format, size, etc.
5685          */
5686      }
5687   }
5688   _mesa_unlock_texture(ctx, texObj);
5689}
5690
5691
5692enum tex_mode {
5693   /* Use bound texture to current unit */
5694   TEX_MODE_CURRENT_NO_ERROR = 0,
5695   TEX_MODE_CURRENT_ERROR,
5696   /* Use the specified texture name */
5697   TEX_MODE_DSA_NO_ERROR,
5698   TEX_MODE_DSA_ERROR,
5699   /* Use the specified texture name + target */
5700   TEX_MODE_EXT_DSA_TEXTURE,
5701   /* Use the specified texture unit + target */
5702   TEX_MODE_EXT_DSA_TEXUNIT,
5703};
5704
5705
5706static void
5707compressed_tex_sub_image(unsigned dim, GLenum target, GLuint textureOrIndex,
5708                         GLint level, GLint xoffset, GLint yoffset,
5709                         GLint zoffset, GLsizei width, GLsizei height,
5710                         GLsizei depth, GLenum format, GLsizei imageSize,
5711                         const GLvoid *data, enum tex_mode mode,
5712                         const char *caller)
5713{
5714   struct gl_texture_object *texObj = NULL;
5715   struct gl_texture_image *texImage;
5716   bool no_error = false;
5717   GET_CURRENT_CONTEXT(ctx);
5718
5719   switch (mode) {
5720      case TEX_MODE_DSA_ERROR:
5721         assert(target == 0);
5722         texObj = _mesa_lookup_texture_err(ctx, textureOrIndex, caller);
5723         if (texObj)
5724            target = texObj->Target;
5725         break;
5726      case TEX_MODE_DSA_NO_ERROR:
5727         assert(target == 0);
5728         texObj = _mesa_lookup_texture(ctx, textureOrIndex);
5729         if (texObj)
5730            target = texObj->Target;
5731         no_error = true;
5732         break;
5733      case TEX_MODE_EXT_DSA_TEXTURE:
5734         texObj = _mesa_lookup_or_create_texture(ctx, target, textureOrIndex,
5735                                                 false, true, caller);
5736         break;
5737      case TEX_MODE_EXT_DSA_TEXUNIT:
5738         texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
5739                                                         textureOrIndex,
5740                                                         false,
5741                                                         caller);
5742         break;
5743      case TEX_MODE_CURRENT_NO_ERROR:
5744         no_error = true;
5745         FALLTHROUGH;
5746      case TEX_MODE_CURRENT_ERROR:
5747      default:
5748         assert(textureOrIndex == 0);
5749         break;
5750   }
5751
5752   if (!no_error &&
5753       compressed_subtexture_target_check(ctx, target, dim, format,
5754                                          mode == TEX_MODE_DSA_ERROR,
5755                                          caller)) {
5756      return;
5757   }
5758
5759   if (mode == TEX_MODE_CURRENT_NO_ERROR ||
5760       mode == TEX_MODE_CURRENT_ERROR) {
5761      texObj = _mesa_get_current_tex_object(ctx, target);
5762   }
5763
5764   if (!texObj)
5765      return;
5766
5767   if (!no_error &&
5768       compressed_subtexture_error_check(ctx, dim, texObj, target, level,
5769                                         xoffset, yoffset, zoffset, width,
5770                                         height, depth, format,
5771                                         imageSize, data, caller)) {
5772      return;
5773   }
5774
5775   /* Must handle special case GL_TEXTURE_CUBE_MAP. */
5776   if (dim == 3 &&
5777       (mode == TEX_MODE_DSA_ERROR || mode == TEX_MODE_DSA_NO_ERROR) &&
5778       texObj->Target == GL_TEXTURE_CUBE_MAP) {
5779      const char *pixels = data;
5780      GLint image_stride;
5781
5782      /* Make sure the texture object is a proper cube.
5783       * (See texturesubimage in teximage.c for details on why this check is
5784       * performed.)
5785       */
5786      if (!no_error && !_mesa_cube_level_complete(texObj, level)) {
5787         _mesa_error(ctx, GL_INVALID_OPERATION,
5788                     "glCompressedTextureSubImage3D(cube map incomplete)");
5789         return;
5790      }
5791
5792      /* Copy in each face. */
5793      for (int i = zoffset; i < zoffset + depth; ++i) {
5794         texImage = texObj->Image[i][level];
5795         assert(texImage);
5796
5797         compressed_texture_sub_image(ctx, 3, texObj, texImage,
5798                                      texObj->Target, level, xoffset, yoffset,
5799                                      0, width, height, 1, format,
5800                                      imageSize, pixels);
5801
5802         /* Compressed images don't have a client format */
5803         image_stride = _mesa_format_image_size(texImage->TexFormat,
5804                                                texImage->Width,
5805                                                texImage->Height, 1);
5806
5807         pixels += image_stride;
5808         imageSize -= image_stride;
5809      }
5810   } else {
5811      texImage = _mesa_select_tex_image(texObj, target, level);
5812      assert(texImage);
5813
5814      compressed_texture_sub_image(ctx, dim, texObj, texImage, target, level,
5815                                   xoffset, yoffset, zoffset, width, height,
5816                                   depth, format, imageSize, data);
5817   }
5818}
5819
5820
5821void GLAPIENTRY
5822_mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level,
5823                                       GLint xoffset, GLsizei width,
5824                                       GLenum format, GLsizei imageSize,
5825                                       const GLvoid *data)
5826{
5827   compressed_tex_sub_image(1, target, 0,
5828                            level, xoffset, 0, 0, width,
5829                            1, 1, format, imageSize, data,
5830                            TEX_MODE_CURRENT_NO_ERROR,
5831                            "glCompressedTexSubImage1D");
5832}
5833
5834
5835void GLAPIENTRY
5836_mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset,
5837                              GLsizei width, GLenum format,
5838                              GLsizei imageSize, const GLvoid *data)
5839{
5840   compressed_tex_sub_image(1, target, 0,
5841                            level, xoffset, 0, 0, width,
5842                            1, 1, format, imageSize, data,
5843                            TEX_MODE_CURRENT_ERROR,
5844                            "glCompressedTexSubImage1D");
5845}
5846
5847
5848void GLAPIENTRY
5849_mesa_CompressedTextureSubImage1D_no_error(GLuint texture, GLint level,
5850                                           GLint xoffset, GLsizei width,
5851                                           GLenum format, GLsizei imageSize,
5852                                           const GLvoid *data)
5853{
5854   compressed_tex_sub_image(1, 0, texture,
5855                            level, xoffset, 0, 0,
5856                            width, 1, 1, format, imageSize, data,
5857                            TEX_MODE_DSA_NO_ERROR,
5858                            "glCompressedTextureSubImage1D");
5859}
5860
5861
5862void GLAPIENTRY
5863_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset,
5864                                  GLsizei width, GLenum format,
5865                                  GLsizei imageSize, const GLvoid *data)
5866{
5867   compressed_tex_sub_image(1, 0, texture,
5868                            level, xoffset, 0, 0,
5869                            width, 1, 1, format, imageSize, data,
5870                            TEX_MODE_DSA_ERROR,
5871                            "glCompressedTextureSubImage1D");
5872}
5873
5874
5875void GLAPIENTRY
5876_mesa_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target,
5877                                     GLint level, GLint xoffset,
5878                                     GLsizei width, GLenum format,
5879                                     GLsizei imageSize, const GLvoid *data)
5880{
5881   compressed_tex_sub_image(1, target, texture, level, xoffset, 0,
5882                            0, width, 1, 1, format, imageSize,
5883                            data,
5884                            TEX_MODE_EXT_DSA_TEXTURE,
5885                            "glCompressedTextureSubImage1DEXT");
5886}
5887
5888
5889void GLAPIENTRY
5890_mesa_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target,
5891                                      GLint level, GLint xoffset,
5892                                      GLsizei width, GLenum format,
5893                                      GLsizei imageSize, const GLvoid *data)
5894{
5895   compressed_tex_sub_image(1, target, texunit - GL_TEXTURE0, level,
5896                            xoffset, 0, 0, width, 1, 1, format, imageSize,
5897                            data,
5898                            TEX_MODE_EXT_DSA_TEXUNIT,
5899                            "glCompressedMultiTexSubImage1DEXT");
5900}
5901
5902
5903void GLAPIENTRY
5904_mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level,
5905                                       GLint xoffset, GLint yoffset,
5906                                       GLsizei width, GLsizei height,
5907                                       GLenum format, GLsizei imageSize,
5908                                       const GLvoid *data)
5909{
5910   compressed_tex_sub_image(2, target, 0, level,
5911                            xoffset, yoffset, 0,
5912                            width, height, 1, format, imageSize, data,
5913                            TEX_MODE_CURRENT_NO_ERROR,
5914                            "glCompressedTexSubImage2D");
5915}
5916
5917
5918void GLAPIENTRY
5919_mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset,
5920                              GLint yoffset, GLsizei width, GLsizei height,
5921                              GLenum format, GLsizei imageSize,
5922                              const GLvoid *data)
5923{
5924   compressed_tex_sub_image(2, target, 0, level,
5925                            xoffset, yoffset, 0,
5926                            width, height, 1, format, imageSize, data,
5927                            TEX_MODE_CURRENT_ERROR,
5928                            "glCompressedTexSubImage2D");
5929}
5930
5931
5932void GLAPIENTRY
5933_mesa_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target,
5934                                     GLint level, GLint xoffset,
5935                                     GLint yoffset, GLsizei width,
5936                                     GLsizei height, GLenum format,
5937                                     GLsizei imageSize, const GLvoid *data)
5938{
5939   compressed_tex_sub_image(2, target, texture, level, xoffset,
5940                            yoffset, 0, width, height, 1, format,
5941                            imageSize, data,
5942                            TEX_MODE_EXT_DSA_TEXTURE,
5943                            "glCompressedTextureSubImage2DEXT");
5944}
5945
5946
5947void GLAPIENTRY
5948_mesa_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target,
5949                                      GLint level, GLint xoffset, GLint yoffset,
5950                                      GLsizei width, GLsizei height, GLenum format,
5951                                      GLsizei imageSize, const GLvoid *data)
5952{
5953   compressed_tex_sub_image(2, target, texunit - GL_TEXTURE0, level,
5954                            xoffset, yoffset, 0, width, height, 1, format,
5955                            imageSize, data,
5956                            TEX_MODE_EXT_DSA_TEXUNIT,
5957                            "glCompressedMultiTexSubImage2DEXT");
5958}
5959
5960
5961void GLAPIENTRY
5962_mesa_CompressedTextureSubImage2D_no_error(GLuint texture, GLint level,
5963                                           GLint xoffset, GLint yoffset,
5964                                           GLsizei width, GLsizei height,
5965                                           GLenum format, GLsizei imageSize,
5966                                           const GLvoid *data)
5967{
5968   compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0,
5969                            width, height, 1, format, imageSize, data,
5970                            TEX_MODE_DSA_NO_ERROR,
5971                            "glCompressedTextureSubImage2D");
5972}
5973
5974
5975void GLAPIENTRY
5976_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset,
5977                                  GLint yoffset,
5978                                  GLsizei width, GLsizei height,
5979                                  GLenum format, GLsizei imageSize,
5980                                  const GLvoid *data)
5981{
5982   compressed_tex_sub_image(2, 0, texture, level, xoffset, yoffset, 0,
5983                            width, height, 1, format, imageSize, data,
5984                            TEX_MODE_DSA_ERROR,
5985                            "glCompressedTextureSubImage2D");
5986}
5987
5988void GLAPIENTRY
5989_mesa_CompressedTexSubImage3D_no_error(GLenum target, GLint level,
5990                                       GLint xoffset, GLint yoffset,
5991                                       GLint zoffset, GLsizei width,
5992                                       GLsizei height, GLsizei depth,
5993                                       GLenum format, GLsizei imageSize,
5994                                       const GLvoid *data)
5995{
5996   compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset,
5997                            zoffset, width, height, depth, format,
5998                            imageSize, data,
5999                            TEX_MODE_CURRENT_NO_ERROR,
6000                            "glCompressedTexSubImage3D");
6001}
6002
6003void GLAPIENTRY
6004_mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset,
6005                              GLint yoffset, GLint zoffset, GLsizei width,
6006                              GLsizei height, GLsizei depth, GLenum format,
6007                              GLsizei imageSize, const GLvoid *data)
6008{
6009   compressed_tex_sub_image(3, target, 0, level, xoffset, yoffset,
6010                            zoffset, width, height, depth, format,
6011                            imageSize, data,
6012                            TEX_MODE_CURRENT_ERROR,
6013                            "glCompressedTexSubImage3D");
6014}
6015
6016void GLAPIENTRY
6017_mesa_CompressedTextureSubImage3D_no_error(GLuint texture, GLint level,
6018                                           GLint xoffset, GLint yoffset,
6019                                           GLint zoffset, GLsizei width,
6020                                           GLsizei height, GLsizei depth,
6021                                           GLenum format, GLsizei imageSize,
6022                                           const GLvoid *data)
6023{
6024   compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset,
6025                            zoffset, width, height, depth, format,
6026                            imageSize, data,
6027                            TEX_MODE_DSA_NO_ERROR,
6028                            "glCompressedTextureSubImage3D");
6029}
6030
6031void GLAPIENTRY
6032_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset,
6033                                  GLint yoffset, GLint zoffset, GLsizei width,
6034                                  GLsizei height, GLsizei depth,
6035                                  GLenum format, GLsizei imageSize,
6036                                  const GLvoid *data)
6037{
6038   compressed_tex_sub_image(3, 0, texture, level, xoffset, yoffset,
6039                            zoffset, width, height, depth, format,
6040                            imageSize, data,
6041                            TEX_MODE_DSA_ERROR,
6042                            "glCompressedTextureSubImage3D");
6043}
6044
6045
6046void GLAPIENTRY
6047_mesa_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target,
6048                                     GLint level, GLint xoffset,
6049                                     GLint yoffset, GLint zoffset,
6050                                     GLsizei width, GLsizei height,
6051                                     GLsizei depth, GLenum format,
6052                                     GLsizei imageSize, const GLvoid *data)
6053{
6054   compressed_tex_sub_image(3, target, texture, level, xoffset, yoffset,
6055                            zoffset, width, height, depth, format,
6056                            imageSize, data,
6057                            TEX_MODE_EXT_DSA_TEXTURE,
6058                            "glCompressedTextureSubImage3DEXT");
6059}
6060
6061
6062void GLAPIENTRY
6063_mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target,
6064                                      GLint level, GLint xoffset, GLint yoffset,
6065                                      GLint zoffset, GLsizei width, GLsizei height,
6066                                      GLsizei depth, GLenum format,
6067                                      GLsizei imageSize, const GLvoid *data)
6068{
6069   compressed_tex_sub_image(3, target, texunit - GL_TEXTURE0, level,
6070                            xoffset, yoffset, zoffset, width, height, depth,
6071                            format, imageSize, data,
6072                            TEX_MODE_EXT_DSA_TEXUNIT,
6073                            "glCompressedMultiTexSubImage3DEXT");
6074}
6075
6076
6077mesa_format
6078_mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat)
6079{
6080   if (ctx->API == API_OPENGL_COMPAT) {
6081      switch (internalFormat) {
6082      case GL_ALPHA8:
6083         return MESA_FORMAT_A_UNORM8;
6084      case GL_ALPHA16:
6085         return MESA_FORMAT_A_UNORM16;
6086      case GL_ALPHA16F_ARB:
6087         return MESA_FORMAT_A_FLOAT16;
6088      case GL_ALPHA32F_ARB:
6089         return MESA_FORMAT_A_FLOAT32;
6090      case GL_ALPHA8I_EXT:
6091         return MESA_FORMAT_A_SINT8;
6092      case GL_ALPHA16I_EXT:
6093         return MESA_FORMAT_A_SINT16;
6094      case GL_ALPHA32I_EXT:
6095         return MESA_FORMAT_A_SINT32;
6096      case GL_ALPHA8UI_EXT:
6097         return MESA_FORMAT_A_UINT8;
6098      case GL_ALPHA16UI_EXT:
6099         return MESA_FORMAT_A_UINT16;
6100      case GL_ALPHA32UI_EXT:
6101         return MESA_FORMAT_A_UINT32;
6102      case GL_LUMINANCE8:
6103         return MESA_FORMAT_L_UNORM8;
6104      case GL_LUMINANCE16:
6105         return MESA_FORMAT_L_UNORM16;
6106      case GL_LUMINANCE16F_ARB:
6107         return MESA_FORMAT_L_FLOAT16;
6108      case GL_LUMINANCE32F_ARB:
6109         return MESA_FORMAT_L_FLOAT32;
6110      case GL_LUMINANCE8I_EXT:
6111         return MESA_FORMAT_L_SINT8;
6112      case GL_LUMINANCE16I_EXT:
6113         return MESA_FORMAT_L_SINT16;
6114      case GL_LUMINANCE32I_EXT:
6115         return MESA_FORMAT_L_SINT32;
6116      case GL_LUMINANCE8UI_EXT:
6117         return MESA_FORMAT_L_UINT8;
6118      case GL_LUMINANCE16UI_EXT:
6119         return MESA_FORMAT_L_UINT16;
6120      case GL_LUMINANCE32UI_EXT:
6121         return MESA_FORMAT_L_UINT32;
6122      case GL_LUMINANCE8_ALPHA8:
6123         return MESA_FORMAT_LA_UNORM8;
6124      case GL_LUMINANCE16_ALPHA16:
6125         return MESA_FORMAT_LA_UNORM16;
6126      case GL_LUMINANCE_ALPHA16F_ARB:
6127         return MESA_FORMAT_LA_FLOAT16;
6128      case GL_LUMINANCE_ALPHA32F_ARB:
6129         return MESA_FORMAT_LA_FLOAT32;
6130      case GL_LUMINANCE_ALPHA8I_EXT:
6131         return MESA_FORMAT_LA_SINT8;
6132      case GL_LUMINANCE_ALPHA16I_EXT:
6133         return MESA_FORMAT_LA_SINT16;
6134      case GL_LUMINANCE_ALPHA32I_EXT:
6135         return MESA_FORMAT_LA_SINT32;
6136      case GL_LUMINANCE_ALPHA8UI_EXT:
6137         return MESA_FORMAT_LA_UINT8;
6138      case GL_LUMINANCE_ALPHA16UI_EXT:
6139         return MESA_FORMAT_LA_UINT16;
6140      case GL_LUMINANCE_ALPHA32UI_EXT:
6141         return MESA_FORMAT_LA_UINT32;
6142      case GL_INTENSITY8:
6143         return MESA_FORMAT_I_UNORM8;
6144      case GL_INTENSITY16:
6145         return MESA_FORMAT_I_UNORM16;
6146      case GL_INTENSITY16F_ARB:
6147         return MESA_FORMAT_I_FLOAT16;
6148      case GL_INTENSITY32F_ARB:
6149         return MESA_FORMAT_I_FLOAT32;
6150      case GL_INTENSITY8I_EXT:
6151         return MESA_FORMAT_I_SINT8;
6152      case GL_INTENSITY16I_EXT:
6153         return MESA_FORMAT_I_SINT16;
6154      case GL_INTENSITY32I_EXT:
6155         return MESA_FORMAT_I_SINT32;
6156      case GL_INTENSITY8UI_EXT:
6157         return MESA_FORMAT_I_UINT8;
6158      case GL_INTENSITY16UI_EXT:
6159         return MESA_FORMAT_I_UINT16;
6160      case GL_INTENSITY32UI_EXT:
6161         return MESA_FORMAT_I_UINT32;
6162      default:
6163         break;
6164      }
6165   }
6166
6167   if (_mesa_has_ARB_texture_buffer_object_rgb32(ctx) ||
6168       _mesa_has_OES_texture_buffer(ctx)) {
6169      switch (internalFormat) {
6170      case GL_RGB32F:
6171         return MESA_FORMAT_RGB_FLOAT32;
6172      case GL_RGB32UI:
6173         return MESA_FORMAT_RGB_UINT32;
6174      case GL_RGB32I:
6175         return MESA_FORMAT_RGB_SINT32;
6176      default:
6177         break;
6178      }
6179   }
6180
6181   switch (internalFormat) {
6182   case GL_RGBA8:
6183      return MESA_FORMAT_R8G8B8A8_UNORM;
6184   case GL_RGBA16:
6185      if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx))
6186         return MESA_FORMAT_NONE;
6187      return MESA_FORMAT_RGBA_UNORM16;
6188   case GL_RGBA16F_ARB:
6189      return MESA_FORMAT_RGBA_FLOAT16;
6190   case GL_RGBA32F_ARB:
6191      return MESA_FORMAT_RGBA_FLOAT32;
6192   case GL_RGBA8I_EXT:
6193      return MESA_FORMAT_RGBA_SINT8;
6194   case GL_RGBA16I_EXT:
6195      return MESA_FORMAT_RGBA_SINT16;
6196   case GL_RGBA32I_EXT:
6197      return MESA_FORMAT_RGBA_SINT32;
6198   case GL_RGBA8UI_EXT:
6199      return MESA_FORMAT_RGBA_UINT8;
6200   case GL_RGBA16UI_EXT:
6201      return MESA_FORMAT_RGBA_UINT16;
6202   case GL_RGBA32UI_EXT:
6203      return MESA_FORMAT_RGBA_UINT32;
6204
6205   case GL_RG8:
6206      return MESA_FORMAT_RG_UNORM8;
6207   case GL_RG16:
6208      if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx))
6209         return MESA_FORMAT_NONE;
6210      return MESA_FORMAT_RG_UNORM16;
6211   case GL_RG16F:
6212      return MESA_FORMAT_RG_FLOAT16;
6213   case GL_RG32F:
6214      return MESA_FORMAT_RG_FLOAT32;
6215   case GL_RG8I:
6216      return MESA_FORMAT_RG_SINT8;
6217   case GL_RG16I:
6218      return MESA_FORMAT_RG_SINT16;
6219   case GL_RG32I:
6220      return MESA_FORMAT_RG_SINT32;
6221   case GL_RG8UI:
6222      return MESA_FORMAT_RG_UINT8;
6223   case GL_RG16UI:
6224      return MESA_FORMAT_RG_UINT16;
6225   case GL_RG32UI:
6226      return MESA_FORMAT_RG_UINT32;
6227
6228   case GL_R8:
6229      return MESA_FORMAT_R_UNORM8;
6230   case GL_R16:
6231      if (_mesa_is_gles(ctx) && !_mesa_has_EXT_texture_norm16(ctx))
6232         return MESA_FORMAT_NONE;
6233      return MESA_FORMAT_R_UNORM16;
6234   case GL_R16F:
6235      return MESA_FORMAT_R_FLOAT16;
6236   case GL_R32F:
6237      return MESA_FORMAT_R_FLOAT32;
6238   case GL_R8I:
6239      return MESA_FORMAT_R_SINT8;
6240   case GL_R16I:
6241      return MESA_FORMAT_R_SINT16;
6242   case GL_R32I:
6243      return MESA_FORMAT_R_SINT32;
6244   case GL_R8UI:
6245      return MESA_FORMAT_R_UINT8;
6246   case GL_R16UI:
6247      return MESA_FORMAT_R_UINT16;
6248   case GL_R32UI:
6249      return MESA_FORMAT_R_UINT32;
6250
6251   default:
6252      return MESA_FORMAT_NONE;
6253   }
6254}
6255
6256
6257mesa_format
6258_mesa_validate_texbuffer_format(const struct gl_context *ctx,
6259                                GLenum internalFormat)
6260{
6261   mesa_format format = _mesa_get_texbuffer_format(ctx, internalFormat);
6262   GLenum datatype;
6263
6264   if (format == MESA_FORMAT_NONE)
6265      return MESA_FORMAT_NONE;
6266
6267   datatype = _mesa_get_format_datatype(format);
6268
6269   /* The GL_ARB_texture_buffer_object spec says:
6270    *
6271    *     "If ARB_texture_float is not supported, references to the
6272    *     floating-point internal formats provided by that extension should be
6273    *     removed, and such formats may not be passed to TexBufferARB."
6274    *
6275    * As a result, GL_HALF_FLOAT internal format depends on both
6276    * GL_ARB_texture_float and GL_ARB_half_float_pixel.
6277    */
6278   if ((datatype == GL_FLOAT || datatype == GL_HALF_FLOAT) &&
6279       !ctx->Extensions.ARB_texture_float)
6280      return MESA_FORMAT_NONE;
6281
6282   if (!ctx->Extensions.ARB_texture_rg) {
6283      GLenum base_format = _mesa_get_format_base_format(format);
6284      if (base_format == GL_R || base_format == GL_RG)
6285         return MESA_FORMAT_NONE;
6286   }
6287
6288   if (!ctx->Extensions.ARB_texture_buffer_object_rgb32) {
6289      GLenum base_format = _mesa_get_format_base_format(format);
6290      if (base_format == GL_RGB)
6291         return MESA_FORMAT_NONE;
6292   }
6293   return format;
6294}
6295
6296
6297/**
6298 * Do work common to glTexBuffer, glTexBufferRange, glTextureBuffer
6299 * and glTextureBufferRange, including some error checking.
6300 */
6301static void
6302texture_buffer_range(struct gl_context *ctx,
6303                     struct gl_texture_object *texObj,
6304                     GLenum internalFormat,
6305                     struct gl_buffer_object *bufObj,
6306                     GLintptr offset, GLsizeiptr size,
6307                     const char *caller)
6308{
6309   GLintptr oldOffset = texObj->BufferOffset;
6310   GLsizeiptr oldSize = texObj->BufferSize;
6311   mesa_format format;
6312   mesa_format old_format;
6313
6314   /* NOTE: ARB_texture_buffer_object might not be supported in
6315    * the compatibility profile.
6316    */
6317   if (!_mesa_has_ARB_texture_buffer_object(ctx) &&
6318       !_mesa_has_OES_texture_buffer(ctx)) {
6319      _mesa_error(ctx, GL_INVALID_OPERATION,
6320                  "%s(ARB_texture_buffer_object is not"
6321                  " implemented for the compatibility profile)", caller);
6322      return;
6323   }
6324
6325   if (texObj->HandleAllocated) {
6326      /* The ARB_bindless_texture spec says:
6327       *
6328       * "The error INVALID_OPERATION is generated by TexImage*, CopyTexImage*,
6329       *  CompressedTexImage*, TexBuffer*, TexParameter*, as well as other
6330       *  functions defined in terms of these, if the texture object to be
6331       *  modified is referenced by one or more texture or image handles."
6332       */
6333      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable texture)", caller);
6334      return;
6335   }
6336
6337   format = _mesa_validate_texbuffer_format(ctx, internalFormat);
6338   if (format == MESA_FORMAT_NONE) {
6339      _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalFormat %s)",
6340                  caller, _mesa_enum_to_string(internalFormat));
6341      return;
6342   }
6343
6344   FLUSH_VERTICES(ctx, 0, GL_TEXTURE_BIT);
6345
6346   _mesa_lock_texture(ctx, texObj);
6347   {
6348      _mesa_reference_buffer_object_shared(ctx, &texObj->BufferObject, bufObj);
6349      texObj->BufferObjectFormat = internalFormat;
6350      old_format = texObj->_BufferObjectFormat;
6351      texObj->_BufferObjectFormat = format;
6352      texObj->BufferOffset = offset;
6353      texObj->BufferSize = size;
6354   }
6355   _mesa_unlock_texture(ctx, texObj);
6356
6357   if (old_format != format) {
6358      st_texture_release_all_sampler_views(st_context(ctx), texObj);
6359   } else {
6360      if (offset != oldOffset) {
6361         st_texture_release_all_sampler_views(st_context(ctx), texObj);
6362      }
6363      if (size != oldSize) {
6364         st_texture_release_all_sampler_views(st_context(ctx), texObj);
6365      }
6366   }
6367
6368   ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS;
6369
6370   if (bufObj) {
6371      bufObj->UsageHistory |= USAGE_TEXTURE_BUFFER;
6372   }
6373}
6374
6375
6376/**
6377 * Make sure the texture buffer target is GL_TEXTURE_BUFFER.
6378 * Return true if it is, and return false if it is not
6379 * (and throw INVALID ENUM as dictated in the OpenGL 4.5
6380 * core spec, 02.02.2015, PDF page 245).
6381 */
6382static bool
6383check_texture_buffer_target(struct gl_context *ctx, GLenum target,
6384                            const char *caller, bool dsa)
6385{
6386   if (target != GL_TEXTURE_BUFFER_ARB) {
6387      _mesa_error(ctx, dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM,
6388                  "%s(texture target is not GL_TEXTURE_BUFFER)", caller);
6389      return false;
6390   }
6391   else
6392      return true;
6393}
6394
6395/**
6396 * Check for errors related to the texture buffer range.
6397 * Return false if errors are found, true if none are found.
6398 */
6399static bool
6400check_texture_buffer_range(struct gl_context *ctx,
6401                           struct gl_buffer_object *bufObj,
6402                           GLintptr offset, GLsizeiptr size,
6403                           const char *caller)
6404{
6405   /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6406    * Textures (PDF page 245):
6407    *    "An INVALID_VALUE error is generated if offset is negative, if
6408    *    size is less than or equal to zero, or if offset + size is greater
6409    *    than the value of BUFFER_SIZE for the buffer bound to target."
6410    */
6411   if (offset < 0) {
6412      _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset=%d < 0)", caller,
6413                  (int) offset);
6414      return false;
6415   }
6416
6417   if (size <= 0) {
6418      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d <= 0)", caller,
6419                  (int) size);
6420      return false;
6421   }
6422
6423   if (offset + size > bufObj->Size) {
6424      _mesa_error(ctx, GL_INVALID_VALUE,
6425                  "%s(offset=%d + size=%d > buffer_size=%d)", caller,
6426                  (int) offset, (int) size, (int) bufObj->Size);
6427      return false;
6428   }
6429
6430   /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6431    * Textures (PDF page 245):
6432    *    "An INVALID_VALUE error is generated if offset is not an integer
6433    *    multiple of the value of TEXTURE_BUFFER_OFFSET_ALIGNMENT."
6434    */
6435   if (offset % ctx->Const.TextureBufferOffsetAlignment) {
6436      _mesa_error(ctx, GL_INVALID_VALUE,
6437                  "%s(invalid offset alignment)", caller);
6438      return false;
6439   }
6440
6441   return true;
6442}
6443
6444
6445/** GL_ARB_texture_buffer_object */
6446void GLAPIENTRY
6447_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer)
6448{
6449   struct gl_texture_object *texObj;
6450   struct gl_buffer_object *bufObj;
6451
6452   GET_CURRENT_CONTEXT(ctx);
6453
6454   /* Need to catch a bad target before it gets to
6455    * _mesa_get_current_tex_object.
6456    */
6457   if (!check_texture_buffer_target(ctx, target, "glTexBuffer", false))
6458      return;
6459
6460   if (buffer) {
6461      bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBuffer");
6462      if (!bufObj)
6463         return;
6464   } else
6465      bufObj = NULL;
6466
6467   texObj = _mesa_get_current_tex_object(ctx, target);
6468   if (!texObj)
6469      return;
6470
6471   texture_buffer_range(ctx, texObj, internalFormat, bufObj, 0,
6472                        buffer ? -1 : 0, "glTexBuffer");
6473}
6474
6475
6476/** GL_ARB_texture_buffer_range */
6477void GLAPIENTRY
6478_mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer,
6479                     GLintptr offset, GLsizeiptr size)
6480{
6481   struct gl_texture_object *texObj;
6482   struct gl_buffer_object *bufObj;
6483
6484   GET_CURRENT_CONTEXT(ctx);
6485
6486   /* Need to catch a bad target before it gets to
6487    * _mesa_get_current_tex_object.
6488    */
6489   if (!check_texture_buffer_target(ctx, target, "glTexBufferRange", false))
6490      return;
6491
6492   if (buffer) {
6493      bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTexBufferRange");
6494      if (!bufObj)
6495         return;
6496
6497      if (!check_texture_buffer_range(ctx, bufObj, offset, size,
6498          "glTexBufferRange"))
6499         return;
6500
6501   } else {
6502      /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6503       * Textures (PDF page 254):
6504       *    "If buffer is zero, then any buffer object attached to the buffer
6505       *    texture is detached, the values offset and size are ignored and
6506       *    the state for offset and size for the buffer texture are reset to
6507       *    zero."
6508       */
6509      offset = 0;
6510      size = 0;
6511      bufObj = NULL;
6512   }
6513
6514   texObj = _mesa_get_current_tex_object(ctx, target);
6515   if (!texObj)
6516      return;
6517
6518   texture_buffer_range(ctx, texObj, internalFormat, bufObj,
6519                        offset, size, "glTexBufferRange");
6520}
6521
6522
6523/** GL_ARB_texture_buffer_range + GL_EXT_direct_state_access */
6524void GLAPIENTRY
6525_mesa_TextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalFormat,
6526                            GLuint buffer, GLintptr offset, GLsizeiptr size)
6527{
6528   struct gl_texture_object *texObj;
6529   struct gl_buffer_object *bufObj;
6530
6531   GET_CURRENT_CONTEXT(ctx);
6532
6533   texObj = _mesa_lookup_or_create_texture(ctx, target, texture, false, true,
6534                                           "glTextureBufferRangeEXT");
6535   if (!texObj)
6536      return;
6537
6538   if (!check_texture_buffer_target(ctx, target, "glTextureBufferRangeEXT", true))
6539      return;
6540
6541   if (buffer) {
6542      bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBufferRangeEXT");
6543      if (!bufObj)
6544         return;
6545
6546      if (!check_texture_buffer_range(ctx, bufObj, offset, size,
6547          "glTextureBufferRangeEXT"))
6548         return;
6549
6550   } else {
6551      /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6552       * Textures (PDF page 254):
6553       *    "If buffer is zero, then any buffer object attached to the buffer
6554       *    texture is detached, the values offset and size are ignored and
6555       *    the state for offset and size for the buffer texture are reset to
6556       *    zero."
6557       */
6558      offset = 0;
6559      size = 0;
6560      bufObj = NULL;
6561   }
6562
6563   texture_buffer_range(ctx, texObj, internalFormat, bufObj,
6564                        offset, size, "glTextureBufferRangeEXT");
6565}
6566
6567
6568void GLAPIENTRY
6569_mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer)
6570{
6571   struct gl_texture_object *texObj;
6572   struct gl_buffer_object *bufObj;
6573
6574   GET_CURRENT_CONTEXT(ctx);
6575
6576   if (buffer) {
6577      bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer");
6578      if (!bufObj)
6579         return;
6580   } else
6581      bufObj = NULL;
6582
6583   /* Get the texture object by Name. */
6584   texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBuffer");
6585   if (!texObj)
6586      return;
6587
6588   if (!check_texture_buffer_target(ctx, texObj->Target, "glTextureBuffer", true))
6589      return;
6590
6591   texture_buffer_range(ctx, texObj, internalFormat,
6592                        bufObj, 0, buffer ? -1 : 0, "glTextureBuffer");
6593}
6594
6595void GLAPIENTRY
6596_mesa_TextureBufferEXT(GLuint texture, GLenum target,
6597                       GLenum internalFormat, GLuint buffer)
6598{
6599   struct gl_texture_object *texObj;
6600   struct gl_buffer_object *bufObj;
6601
6602   GET_CURRENT_CONTEXT(ctx);
6603
6604   if (buffer) {
6605      bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glTextureBuffer");
6606      if (!bufObj)
6607         return;
6608   } else
6609      bufObj = NULL;
6610
6611   /* Get the texture object by Name. */
6612   texObj = _mesa_lookup_or_create_texture(ctx, target, texture,
6613                                           false, true,
6614                                           "glTextureBufferEXT");
6615
6616   if (!texObj ||
6617       !check_texture_buffer_target(ctx, texObj->Target, "glTextureBufferEXT", true))
6618      return;
6619
6620   texture_buffer_range(ctx, texObj, internalFormat,
6621                        bufObj, 0, buffer ? -1 : 0, "glTextureBufferEXT");
6622}
6623
6624void GLAPIENTRY
6625_mesa_MultiTexBufferEXT(GLenum texunit, GLenum target,
6626                        GLenum internalFormat, GLuint buffer)
6627{
6628   struct gl_texture_object *texObj;
6629   struct gl_buffer_object *bufObj;
6630
6631   GET_CURRENT_CONTEXT(ctx);
6632
6633   if (buffer) {
6634      bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMultiTexBufferEXT");
6635      if (!bufObj)
6636         return;
6637   } else
6638      bufObj = NULL;
6639
6640   /* Get the texture object */
6641   texObj = _mesa_get_texobj_by_target_and_texunit(ctx, target,
6642                                                   texunit - GL_TEXTURE0,
6643                                                   true,
6644                                                   "glMultiTexBufferEXT");
6645
6646   if (!texObj ||
6647       !check_texture_buffer_target(ctx, texObj->Target, "glMultiTexBufferEXT", false))
6648      return;
6649
6650   texture_buffer_range(ctx, texObj, internalFormat,
6651                        bufObj, 0, buffer ? -1 : 0, "glMultiTexBufferEXT");
6652}
6653
6654void GLAPIENTRY
6655_mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer,
6656                         GLintptr offset, GLsizeiptr size)
6657{
6658   struct gl_texture_object *texObj;
6659   struct gl_buffer_object *bufObj;
6660
6661   GET_CURRENT_CONTEXT(ctx);
6662
6663   if (buffer) {
6664      bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
6665                                          "glTextureBufferRange");
6666      if (!bufObj)
6667         return;
6668
6669      if (!check_texture_buffer_range(ctx, bufObj, offset, size,
6670          "glTextureBufferRange"))
6671         return;
6672
6673   } else {
6674      /* OpenGL 4.5 core spec (02.02.2015) says in Section 8.9 Buffer
6675       * Textures (PDF page 254):
6676       *    "If buffer is zero, then any buffer object attached to the buffer
6677       *    texture is detached, the values offset and size are ignored and
6678       *    the state for offset and size for the buffer texture are reset to
6679       *    zero."
6680       */
6681      offset = 0;
6682      size = 0;
6683      bufObj = NULL;
6684   }
6685
6686   /* Get the texture object by Name. */
6687   texObj = _mesa_lookup_texture_err(ctx, texture, "glTextureBufferRange");
6688   if (!texObj)
6689      return;
6690
6691   if (!check_texture_buffer_target(ctx, texObj->Target,
6692       "glTextureBufferRange", true))
6693      return;
6694
6695   texture_buffer_range(ctx, texObj, internalFormat,
6696                        bufObj, offset, size, "glTextureBufferRange");
6697}
6698
6699GLboolean
6700_mesa_is_renderable_texture_format(const struct gl_context *ctx,
6701                                   GLenum internalformat)
6702{
6703   /* Everything that is allowed for renderbuffers,
6704    * except for a base format of GL_STENCIL_INDEX, unless supported.
6705    */
6706   GLenum baseFormat = _mesa_base_fbo_format(ctx, internalformat);
6707   if (ctx->Extensions.ARB_texture_stencil8)
6708      return baseFormat != 0;
6709   else
6710      return baseFormat != 0 && baseFormat != GL_STENCIL_INDEX;
6711}
6712
6713
6714/** GL_ARB_texture_multisample */
6715static GLboolean
6716check_multisample_target(GLuint dims, GLenum target, bool dsa)
6717{
6718   switch(target) {
6719   case GL_TEXTURE_2D_MULTISAMPLE:
6720      return dims == 2;
6721   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
6722      return dims == 2 && !dsa;
6723   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
6724      return dims == 3;
6725   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
6726      return dims == 3 && !dsa;
6727   default:
6728      return GL_FALSE;
6729   }
6730}
6731
6732
6733static void
6734texture_image_multisample(struct gl_context *ctx, GLuint dims,
6735                          struct gl_texture_object *texObj,
6736                          struct gl_memory_object *memObj,
6737                          GLenum target, GLsizei samples,
6738                          GLint internalformat, GLsizei width,
6739                          GLsizei height, GLsizei depth,
6740                          GLboolean fixedsamplelocations,
6741                          GLboolean immutable, GLuint64 offset,
6742                          const char *func)
6743{
6744   struct gl_texture_image *texImage;
6745   GLboolean sizeOK, dimensionsOK, samplesOK;
6746   mesa_format texFormat;
6747   GLenum sample_count_error;
6748   bool dsa = strstr(func, "ture") ? true : false;
6749
6750   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) {
6751      _mesa_debug(ctx, "%s(target=%s, samples=%d, internalformat=%s)\n", func,
6752                  _mesa_enum_to_string(target), samples, _mesa_enum_to_string(internalformat));
6753   }
6754
6755   if (!((ctx->Extensions.ARB_texture_multisample
6756         && _mesa_is_desktop_gl(ctx))) && !_mesa_is_gles31(ctx)) {
6757      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
6758      return;
6759   }
6760
6761   if (samples < 1) {
6762      _mesa_error(ctx, GL_INVALID_VALUE, "%s(samples < 1)", func);
6763      return;
6764   }
6765
6766   if (!check_multisample_target(dims, target, dsa)) {
6767      GLenum err = dsa ? GL_INVALID_OPERATION : GL_INVALID_ENUM;
6768      _mesa_error(ctx, err, "%s(target=%s)", func,
6769                  _mesa_enum_to_string(target));
6770      return;
6771   }
6772
6773   /* check that the specified internalformat is color/depth/stencil-renderable;
6774    * refer GL3.1 spec 4.4.4
6775    */
6776
6777   if (immutable && !_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
6778      _mesa_error(ctx, GL_INVALID_ENUM,
6779            "%s(internalformat=%s not legal for immutable-format)",
6780            func, _mesa_enum_to_string(internalformat));
6781      return;
6782   }
6783
6784   if (!_mesa_is_renderable_texture_format(ctx, internalformat)) {
6785      /* Page 172 of OpenGL ES 3.1 spec says:
6786       *   "An INVALID_ENUM error is generated if sizedinternalformat is not
6787       *   color-renderable, depth-renderable, or stencil-renderable (as
6788       *   defined in section 9.4).
6789       *
6790       *  (Same error is also defined for desktop OpenGL for multisample
6791       *  teximage/texstorage functions.)
6792       */
6793      _mesa_error(ctx, GL_INVALID_ENUM, "%s(internalformat=%s)", func,
6794                  _mesa_enum_to_string(internalformat));
6795      return;
6796   }
6797
6798   sample_count_error = _mesa_check_sample_count(ctx, target,
6799         internalformat, samples, samples);
6800   samplesOK = sample_count_error == GL_NO_ERROR;
6801
6802   /* Page 254 of OpenGL 4.4 spec says:
6803    *   "Proxy arrays for two-dimensional multisample and two-dimensional
6804    *    multisample array textures are operated on in the same way when
6805    *    TexImage2DMultisample is called with target specified as
6806    *    PROXY_TEXTURE_2D_MULTISAMPLE, or TexImage3DMultisample is called
6807    *    with target specified as PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY.
6808    *    However, if samples is not supported, then no error is generated.
6809    */
6810   if (!samplesOK && !_mesa_is_proxy_texture(target)) {
6811      _mesa_error(ctx, sample_count_error, "%s(samples=%d)", func, samples);
6812      return;
6813   }
6814
6815   if (!texObj) {
6816      texObj = _mesa_get_current_tex_object(ctx, target);
6817      if (!texObj)
6818         return;
6819   }
6820
6821   if (immutable && texObj->Name == 0) {
6822      _mesa_error(ctx, GL_INVALID_OPERATION,
6823            "%s(texture object 0)",
6824            func);
6825      return;
6826   }
6827
6828   texImage = _mesa_get_tex_image(ctx, texObj, 0, 0);
6829
6830   if (texImage == NULL) {
6831      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
6832      return;
6833   }
6834
6835   texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
6836         internalformat, GL_NONE, GL_NONE);
6837   assert(texFormat != MESA_FORMAT_NONE);
6838
6839   dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
6840         width, height, depth, 0);
6841
6842   sizeOK = st_TestProxyTexImage(ctx, target, 0, 0, texFormat,
6843                                 samples, width, height, depth);
6844
6845   if (_mesa_is_proxy_texture(target)) {
6846      if (samplesOK && dimensionsOK && sizeOK) {
6847         _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0,
6848                                       internalformat, texFormat,
6849                                       samples, fixedsamplelocations);
6850      }
6851      else {
6852         /* clear all image fields */
6853         clear_teximage_fields(texImage);
6854      }
6855   }
6856   else {
6857      if (!dimensionsOK) {
6858         _mesa_error(ctx, GL_INVALID_VALUE,
6859                     "%s(invalid width=%d or height=%d)", func, width, height);
6860         return;
6861      }
6862
6863      if (!sizeOK) {
6864         _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(texture too large)", func);
6865         return;
6866      }
6867
6868      /* Check if texObj->Immutable is set */
6869      if (texObj->Immutable) {
6870         _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func);
6871         return;
6872      }
6873
6874      if (texObj->IsSparse &&
6875          _mesa_sparse_texture_error_check(ctx, dims, texObj, texFormat, target, 0,
6876                                           width, height, depth, func))
6877         return; /* error was recorded */
6878
6879      st_FreeTextureImageBuffer(ctx, texImage);
6880
6881      _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0,
6882                                    internalformat, texFormat,
6883                                    samples, fixedsamplelocations);
6884
6885      if (width > 0 && height > 0 && depth > 0) {
6886         if (memObj) {
6887            if (!st_SetTextureStorageForMemoryObject(ctx, texObj,
6888                                                     memObj, 1, width,
6889                                                     height, depth,
6890                                                     offset)) {
6891
6892               _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0,
6893                                          internalformat, texFormat);
6894            }
6895         } else {
6896            if (!st_AllocTextureStorage(ctx, texObj, 1,
6897                                        width, height, depth)) {
6898               /* tidy up the texture image state. strictly speaking,
6899                * we're allowed to just leave this in whatever state we
6900                * like, but being tidy is good.
6901                */
6902               _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0,
6903                                          internalformat, texFormat);
6904            }
6905         }
6906      }
6907
6908      texObj->External = GL_FALSE;
6909      texObj->Immutable |= immutable;
6910
6911      if (immutable) {
6912         _mesa_set_texture_view_state(ctx, texObj, target, 1);
6913      }
6914
6915      _mesa_update_fbo_texture(ctx, texObj, 0, 0);
6916   }
6917}
6918
6919
6920void GLAPIENTRY
6921_mesa_TexImage2DMultisample(GLenum target, GLsizei samples,
6922                            GLenum internalformat, GLsizei width,
6923                            GLsizei height, GLboolean fixedsamplelocations)
6924{
6925   GET_CURRENT_CONTEXT(ctx);
6926
6927   texture_image_multisample(ctx, 2, NULL, NULL, target, samples,
6928                             internalformat, width, height, 1,
6929                             fixedsamplelocations, GL_FALSE, 0,
6930                             "glTexImage2DMultisample");
6931}
6932
6933
6934void GLAPIENTRY
6935_mesa_TexImage3DMultisample(GLenum target, GLsizei samples,
6936                            GLenum internalformat, GLsizei width,
6937                            GLsizei height, GLsizei depth,
6938                            GLboolean fixedsamplelocations)
6939{
6940   GET_CURRENT_CONTEXT(ctx);
6941
6942   texture_image_multisample(ctx, 3, NULL, NULL, target, samples,
6943                             internalformat, width, height, depth,
6944                             fixedsamplelocations, GL_FALSE, 0,
6945                             "glTexImage3DMultisample");
6946}
6947
6948static bool
6949valid_texstorage_ms_parameters(GLsizei width, GLsizei height, GLsizei depth,
6950                               unsigned dims)
6951{
6952   GET_CURRENT_CONTEXT(ctx);
6953
6954   if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
6955      _mesa_error(ctx, GL_INVALID_VALUE,
6956                  "glTexStorage%uDMultisample(width=%d,height=%d,depth=%d)",
6957                  dims, width, height, depth);
6958      return false;
6959   }
6960   return true;
6961}
6962
6963void GLAPIENTRY
6964_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples,
6965                              GLenum internalformat, GLsizei width,
6966                              GLsizei height, GLboolean fixedsamplelocations)
6967{
6968   GET_CURRENT_CONTEXT(ctx);
6969
6970   if (!valid_texstorage_ms_parameters(width, height, 1, 2))
6971      return;
6972
6973   texture_image_multisample(ctx, 2, NULL, NULL, target, samples,
6974                             internalformat, width, height, 1,
6975                             fixedsamplelocations, GL_TRUE, 0,
6976                             "glTexStorage2DMultisample");
6977}
6978
6979void GLAPIENTRY
6980_mesa_TexStorage3DMultisample(GLenum target, GLsizei samples,
6981                              GLenum internalformat, GLsizei width,
6982                              GLsizei height, GLsizei depth,
6983                              GLboolean fixedsamplelocations)
6984{
6985   GET_CURRENT_CONTEXT(ctx);
6986
6987   if (!valid_texstorage_ms_parameters(width, height, depth, 3))
6988      return;
6989
6990   texture_image_multisample(ctx, 3, NULL, NULL, target, samples,
6991                             internalformat, width, height, depth,
6992                             fixedsamplelocations, GL_TRUE, 0,
6993                             "glTexStorage3DMultisample");
6994}
6995
6996void GLAPIENTRY
6997_mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples,
6998                                  GLenum internalformat, GLsizei width,
6999                                  GLsizei height,
7000                                  GLboolean fixedsamplelocations)
7001{
7002   struct gl_texture_object *texObj;
7003   GET_CURRENT_CONTEXT(ctx);
7004
7005   texObj = _mesa_lookup_texture_err(ctx, texture,
7006                                     "glTextureStorage2DMultisample");
7007   if (!texObj)
7008      return;
7009
7010   if (!valid_texstorage_ms_parameters(width, height, 1, 2))
7011      return;
7012
7013   texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target,
7014                             samples, internalformat, width, height, 1,
7015                             fixedsamplelocations, GL_TRUE, 0,
7016                             "glTextureStorage2DMultisample");
7017}
7018
7019void GLAPIENTRY
7020_mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples,
7021                                  GLenum internalformat, GLsizei width,
7022                                  GLsizei height, GLsizei depth,
7023                                  GLboolean fixedsamplelocations)
7024{
7025   struct gl_texture_object *texObj;
7026   GET_CURRENT_CONTEXT(ctx);
7027
7028   /* Get the texture object by Name. */
7029   texObj = _mesa_lookup_texture_err(ctx, texture,
7030                                     "glTextureStorage3DMultisample");
7031   if (!texObj)
7032      return;
7033
7034   if (!valid_texstorage_ms_parameters(width, height, depth, 3))
7035      return;
7036
7037   texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples,
7038                             internalformat, width, height, depth,
7039                             fixedsamplelocations, GL_TRUE, 0,
7040                             "glTextureStorage3DMultisample");
7041}
7042
7043void GLAPIENTRY
7044_mesa_TextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples,
7045                                     GLenum internalformat, GLsizei width,
7046                                     GLsizei height,
7047                                     GLboolean fixedsamplelocations)
7048{
7049   struct gl_texture_object *texObj;
7050   GET_CURRENT_CONTEXT(ctx);
7051
7052   texObj = lookup_texture_ext_dsa(ctx, target, texture,
7053                                   "glTextureStorage2DMultisampleEXT");
7054   if (!texObj)
7055      return;
7056
7057   if (!valid_texstorage_ms_parameters(width, height, 1, 2))
7058      return;
7059
7060   texture_image_multisample(ctx, 2, texObj, NULL, texObj->Target,
7061                             samples, internalformat, width, height, 1,
7062                             fixedsamplelocations, GL_TRUE, 0,
7063                             "glTextureStorage2DMultisampleEXT");
7064}
7065
7066void GLAPIENTRY
7067_mesa_TextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples,
7068                                     GLenum internalformat, GLsizei width,
7069                                     GLsizei height, GLsizei depth,
7070                                     GLboolean fixedsamplelocations)
7071{
7072   struct gl_texture_object *texObj;
7073   GET_CURRENT_CONTEXT(ctx);
7074
7075   texObj = lookup_texture_ext_dsa(ctx, target, texture,
7076                                   "glTextureStorage3DMultisampleEXT");
7077   if (!texObj)
7078      return;
7079
7080   if (!valid_texstorage_ms_parameters(width, height, depth, 3))
7081      return;
7082
7083   texture_image_multisample(ctx, 3, texObj, NULL, texObj->Target, samples,
7084                             internalformat, width, height, depth,
7085                             fixedsamplelocations, GL_TRUE, 0,
7086                             "glTextureStorage3DMultisampleEXT");
7087}
7088
7089void
7090_mesa_texture_storage_ms_memory(struct gl_context *ctx, GLuint dims,
7091                                struct gl_texture_object *texObj,
7092                                struct gl_memory_object *memObj,
7093                                GLenum target, GLsizei samples,
7094                                GLenum internalFormat, GLsizei width,
7095                                GLsizei height, GLsizei depth,
7096                                GLboolean fixedSampleLocations,
7097                                GLuint64 offset, const char* func)
7098{
7099   assert(memObj);
7100
7101   texture_image_multisample(ctx, dims, texObj, memObj, target, samples,
7102                             internalFormat, width, height, depth,
7103                             fixedSampleLocations, GL_TRUE, offset,
7104                             func);
7105}
7106