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