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