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