1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2011  VMware, Inc.  All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 /**
26  * \file texstorage.c
27  * GL_ARB_texture_storage functions
28  */
29 
30 #include "glheader.h"
31 #include "context.h"
32 #include "enums.h"
33 
34 #include "macros.h"
35 #include "teximage.h"
36 #include "texobj.h"
37 #include "mipmap.h"
38 #include "texstorage.h"
39 #include "textureview.h"
40 #include "mtypes.h"
41 #include "glformats.h"
42 #include "hash.h"
43 
44 
45 /**
46  * Check if the given texture target is a legal texture object target
47  * for a glTexStorage() command.
48  * This is a bit different than legal_teximage_target() when it comes
49  * to cube maps.
50  */
51 static bool
legal_texobj_target(const struct gl_context * ctx,GLuint dims,GLenum target)52 legal_texobj_target(const struct gl_context *ctx, GLuint dims, GLenum target)
53 {
54    if (dims < 1 || dims > 3) {
55       _mesa_problem(ctx, "invalid dims=%u in legal_texobj_target()", dims);
56       return false;
57    }
58 
59    switch (dims) {
60    case 2:
61       switch (target) {
62       case GL_TEXTURE_2D:
63          return true;
64       case GL_TEXTURE_CUBE_MAP:
65          return ctx->Extensions.ARB_texture_cube_map;
66       }
67       break;
68    case 3:
69       switch (target) {
70       case GL_TEXTURE_3D:
71          return true;
72       case GL_TEXTURE_2D_ARRAY:
73          return ctx->Extensions.EXT_texture_array;
74       case GL_TEXTURE_CUBE_MAP_ARRAY:
75          return _mesa_has_texture_cube_map_array(ctx);
76       }
77       break;
78    }
79 
80    if (!_mesa_is_desktop_gl(ctx))
81       return false;
82 
83    switch (dims) {
84    case 1:
85       switch (target) {
86       case GL_TEXTURE_1D:
87       case GL_PROXY_TEXTURE_1D:
88          return true;
89       default:
90          return false;
91       }
92    case 2:
93       switch (target) {
94       case GL_PROXY_TEXTURE_2D:
95          return true;
96       case GL_PROXY_TEXTURE_CUBE_MAP:
97          return ctx->Extensions.ARB_texture_cube_map;
98       case GL_TEXTURE_RECTANGLE:
99       case GL_PROXY_TEXTURE_RECTANGLE:
100          return ctx->Extensions.NV_texture_rectangle;
101       case GL_TEXTURE_1D_ARRAY:
102       case GL_PROXY_TEXTURE_1D_ARRAY:
103          return ctx->Extensions.EXT_texture_array;
104       default:
105          return false;
106       }
107    case 3:
108       switch (target) {
109       case GL_PROXY_TEXTURE_3D:
110          return true;
111       case GL_PROXY_TEXTURE_2D_ARRAY:
112          return ctx->Extensions.EXT_texture_array;
113       case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
114          return ctx->Extensions.ARB_texture_cube_map_array;
115       default:
116          return false;
117       }
118    default:
119       unreachable("impossible dimensions");
120    }
121 }
122 
123 
124 /** Helper to get a particular texture image in a texture object */
125 static struct gl_texture_image *
get_tex_image(struct gl_context * ctx,struct gl_texture_object * texObj,GLuint face,GLuint level)126 get_tex_image(struct gl_context *ctx,
127               struct gl_texture_object *texObj,
128               GLuint face, GLuint level)
129 {
130    const GLenum faceTarget =
131       (texObj->Target == GL_TEXTURE_CUBE_MAP ||
132        texObj->Target == GL_PROXY_TEXTURE_CUBE_MAP)
133       ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : texObj->Target;
134    return _mesa_get_tex_image(ctx, texObj, faceTarget, level);
135 }
136 
137 
138 
139 static GLboolean
initialize_texture_fields(struct gl_context * ctx,struct gl_texture_object * texObj,GLint levels,GLsizei width,GLsizei height,GLsizei depth,GLenum internalFormat,mesa_format texFormat)140 initialize_texture_fields(struct gl_context *ctx,
141                           struct gl_texture_object *texObj,
142                           GLint levels,
143                           GLsizei width, GLsizei height, GLsizei depth,
144                           GLenum internalFormat, mesa_format texFormat)
145 {
146    const GLenum target = texObj->Target;
147    const GLuint numFaces = _mesa_num_tex_faces(target);
148    GLint level, levelWidth = width, levelHeight = height, levelDepth = depth;
149    GLuint face;
150 
151    /* Set up all the texture object's gl_texture_images */
152    for (level = 0; level < levels; level++) {
153       for (face = 0; face < numFaces; face++) {
154          struct gl_texture_image *texImage =
155             get_tex_image(ctx, texObj, face, level);
156 
157 	 if (!texImage) {
158 	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
159             return GL_FALSE;
160 	 }
161 
162          _mesa_init_teximage_fields(ctx, texImage,
163                                     levelWidth, levelHeight, levelDepth,
164                                     0, internalFormat, texFormat);
165       }
166 
167       _mesa_next_mipmap_level_size(target, 0,
168                                    levelWidth, levelHeight, levelDepth,
169                                    &levelWidth, &levelHeight, &levelDepth);
170    }
171    return GL_TRUE;
172 }
173 
174 
175 /**
176  * Clear all fields of texture object to zeros.  Used for proxy texture tests
177  * and to clean up when a texture memory allocation fails.
178  */
179 static void
clear_texture_fields(struct gl_context * ctx,struct gl_texture_object * texObj)180 clear_texture_fields(struct gl_context *ctx,
181                      struct gl_texture_object *texObj)
182 {
183    const GLenum target = texObj->Target;
184    const GLuint numFaces = _mesa_num_tex_faces(target);
185    GLint level;
186    GLuint face;
187 
188    for (level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) {
189       for (face = 0; face < numFaces; face++) {
190          struct gl_texture_image *texImage =
191             get_tex_image(ctx, texObj, face, level);
192 
193 	 if (!texImage) {
194 	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
195             return;
196 	 }
197 
198          _mesa_clear_texture_image(ctx, texImage);
199       }
200    }
201 }
202 
203 
204 /**
205  * Update/re-validate framebuffer object.
206  */
207 static void
update_fbo_texture(struct gl_context * ctx,struct gl_texture_object * texObj)208 update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
209 {
210    const unsigned numFaces = _mesa_num_tex_faces(texObj->Target);
211    for (int level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) {
212       for (unsigned face = 0; face < numFaces; face++)
213          _mesa_update_fbo_texture(ctx, texObj, face, level);
214    }
215 }
216 
217 
218 GLboolean
_mesa_is_legal_tex_storage_format(const struct gl_context * ctx,GLenum internalformat)219 _mesa_is_legal_tex_storage_format(const struct gl_context *ctx,
220                                   GLenum internalformat)
221 {
222    /* check internal format - note that only sized formats are allowed */
223    switch (internalformat) {
224    case GL_ALPHA:
225    case GL_LUMINANCE:
226    case GL_LUMINANCE_ALPHA:
227    case GL_INTENSITY:
228    case GL_RED:
229    case GL_RG:
230    case GL_RGB:
231    case GL_RGBA:
232    case GL_BGRA:
233    case GL_DEPTH_COMPONENT:
234    case GL_DEPTH_STENCIL:
235    case GL_COMPRESSED_ALPHA:
236    case GL_COMPRESSED_LUMINANCE_ALPHA:
237    case GL_COMPRESSED_LUMINANCE:
238    case GL_COMPRESSED_INTENSITY:
239    case GL_COMPRESSED_RGB:
240    case GL_COMPRESSED_RGBA:
241    case GL_COMPRESSED_SRGB:
242    case GL_COMPRESSED_SRGB_ALPHA:
243    case GL_COMPRESSED_SLUMINANCE:
244    case GL_COMPRESSED_SLUMINANCE_ALPHA:
245    case GL_RED_INTEGER:
246    case GL_GREEN_INTEGER:
247    case GL_BLUE_INTEGER:
248    case GL_ALPHA_INTEGER:
249    case GL_RGB_INTEGER:
250    case GL_RGBA_INTEGER:
251    case GL_BGR_INTEGER:
252    case GL_BGRA_INTEGER:
253    case GL_LUMINANCE_INTEGER_EXT:
254    case GL_LUMINANCE_ALPHA_INTEGER_EXT:
255       /* these unsized formats are illegal */
256       return GL_FALSE;
257    default:
258       return _mesa_base_tex_format(ctx, internalformat) > 0;
259    }
260 }
261 
262 
263 /**
264  * Default ctx->Driver.AllocTextureStorage() handler.
265  *
266  * The driver can override this with a more specific implementation if it
267  * desires, but this can be used to get the texture images allocated using the
268  * usual texture image handling code.  The immutability of
269  * GL_ARB_texture_storage texture layouts is handled by texObj->Immutable
270  * checks at glTexImage* time.
271  */
272 GLboolean
_mesa_AllocTextureStorage_sw(struct gl_context * ctx,struct gl_texture_object * texObj,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth)273 _mesa_AllocTextureStorage_sw(struct gl_context *ctx,
274                              struct gl_texture_object *texObj,
275                              GLsizei levels, GLsizei width,
276                              GLsizei height, GLsizei depth)
277 {
278    const int numFaces = _mesa_num_tex_faces(texObj->Target);
279    int face;
280    int level;
281 
282    (void) width;
283    (void) height;
284    (void) depth;
285 
286    for (face = 0; face < numFaces; face++) {
287       for (level = 0; level < levels; level++) {
288          struct gl_texture_image *const texImage = texObj->Image[face][level];
289          if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage))
290             return GL_FALSE;
291       }
292    }
293 
294    return GL_TRUE;
295 }
296 
297 
298 /**
299  * Do error checking for calls to glTexStorage1/2/3D().
300  * If an error is found, record it with _mesa_error(), unless the target
301  * is a proxy texture.
302  * \return GL_TRUE if any error, GL_FALSE otherwise.
303  */
304 static GLboolean
tex_storage_error_check(struct gl_context * ctx,struct gl_texture_object * texObj,struct gl_memory_object * memObj,GLuint dims,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,bool dsa)305 tex_storage_error_check(struct gl_context *ctx,
306                         struct gl_texture_object *texObj,
307                         struct gl_memory_object *memObj,
308                         GLuint dims, GLenum target,
309                         GLsizei levels, GLenum internalformat,
310                         GLsizei width, GLsizei height, GLsizei depth,
311                         bool dsa)
312 {
313    const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
314                               (memObj ? "Mem" : "");
315 
316    /* Legal format checking has been moved to texstorage and texturestorage in
317     * order to allow meta functions to use legacy formats. */
318 
319    /* size check */
320    if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
321       _mesa_error(ctx, GL_INVALID_VALUE,
322                   "glTex%sStorage%uD(width, height or depth < 1)",
323                   suffix, dims);
324       return GL_TRUE;
325    }
326 
327    if (_mesa_is_compressed_format(ctx, internalformat)) {
328       GLenum err;
329       if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) {
330          _mesa_error(ctx, err,
331                   "glTex%sStorage%dD(internalformat = %s)", suffix, dims,
332                   _mesa_enum_to_string(internalformat));
333          return GL_TRUE;
334       }
335    }
336 
337    /* levels check */
338    if (levels < 1) {
339       _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)",
340                   suffix, dims);
341       return GL_TRUE;
342    }
343 
344    /* check levels against maximum (note different error than above) */
345    if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) {
346       _mesa_error(ctx, GL_INVALID_OPERATION,
347                   "glTex%sStorage%uD(levels too large)",
348                   suffix, dims);
349       return GL_TRUE;
350    }
351 
352    /* check levels against width/height/depth */
353    if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) {
354       _mesa_error(ctx, GL_INVALID_OPERATION,
355                   "glTex%sStorage%uD(too many levels"
356                   " for max texture dimension)",
357                   suffix, dims);
358       return GL_TRUE;
359    }
360 
361    /* non-default texture object check */
362    if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) {
363       _mesa_error(ctx, GL_INVALID_OPERATION,
364                   "glTex%sStorage%uD(texture object 0)",
365                   suffix, dims);
366       return GL_TRUE;
367    }
368 
369    /* Check if texObj->Immutable is set */
370    if (!_mesa_is_proxy_texture(target) && texObj->Immutable) {
371       _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)",
372                   suffix, dims);
373       return GL_TRUE;
374    }
375 
376    /* additional checks for depth textures */
377    if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) {
378       _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(bad target for texture)",
379                   suffix, dims);
380       return GL_TRUE;
381    }
382 
383    return GL_FALSE;
384 }
385 
386 
387 /**
388  * Helper that does the storage allocation for _mesa_TexStorage1/2/3D()
389  * and _mesa_TextureStorage1/2/3D().
390  */
391 static ALWAYS_INLINE void
texture_storage(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,struct gl_memory_object * memObj,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLuint64 offset,bool dsa,bool no_error)392 texture_storage(struct gl_context *ctx, GLuint dims,
393                 struct gl_texture_object *texObj,
394                 struct gl_memory_object *memObj, GLenum target,
395                 GLsizei levels, GLenum internalformat, GLsizei width,
396                 GLsizei height, GLsizei depth, GLuint64 offset, bool dsa,
397                 bool no_error)
398 {
399    GLboolean sizeOK = GL_TRUE, dimensionsOK = GL_TRUE;
400    mesa_format texFormat;
401    const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
402                               (memObj ? "Mem" : "");
403 
404    assert(texObj);
405 
406    if (!no_error) {
407       if (tex_storage_error_check(ctx, texObj, memObj, dims, target, levels,
408                                   internalformat, width, height, depth, dsa)) {
409          return; /* error was recorded */
410       }
411    }
412 
413    texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
414                                            internalformat, GL_NONE, GL_NONE);
415 
416    if (!no_error) {
417       /* check that width, height, depth are legal for the mipmap level */
418       dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
419                                                      width, height, depth, 0);
420 
421       sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, levels, 0, texFormat,
422                                              1, width, height, depth);
423    }
424 
425    if (_mesa_is_proxy_texture(target)) {
426       if (dimensionsOK && sizeOK) {
427          initialize_texture_fields(ctx, texObj, levels, width, height, depth,
428                                    internalformat, texFormat);
429       }
430       else {
431          /* clear all image fields for [levels] */
432          clear_texture_fields(ctx, texObj);
433       }
434    }
435    else {
436       if (!no_error) {
437          if (!dimensionsOK) {
438             _mesa_error(ctx, GL_INVALID_VALUE,
439                         "glTex%sStorage%uD(invalid width, height or depth)",
440                         suffix, dims);
441             return;
442          }
443 
444          if (!sizeOK) {
445             _mesa_error(ctx, GL_OUT_OF_MEMORY,
446                         "glTex%sStorage%uD(texture too large)",
447                         suffix, dims);
448             return;
449          }
450       }
451 
452       assert(levels > 0);
453       assert(width > 0);
454       assert(height > 0);
455       assert(depth > 0);
456 
457       if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth,
458                                      internalformat, texFormat)) {
459          return;
460       }
461 
462       /* Setup the backing memory */
463       if (memObj) {
464          if (!ctx->Driver.SetTextureStorageForMemoryObject(ctx, texObj, memObj,
465                                                            levels,
466                                                            width, height, depth,
467                                                            offset)) {
468 
469             clear_texture_fields(ctx, texObj);
470             return;
471          }
472       }
473       else {
474          if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
475                                               width, height, depth)) {
476             /* Reset the texture images' info to zeros.
477              * Strictly speaking, we probably don't have to do this since
478              * generating GL_OUT_OF_MEMORY can leave things in an undefined
479              * state but this puts things in a consistent state.
480              */
481             clear_texture_fields(ctx, texObj);
482             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
483                         suffix, dims);
484             return;
485          }
486       }
487 
488       _mesa_set_texture_view_state(ctx, texObj, target, levels);
489 
490       update_fbo_texture(ctx, texObj);
491    }
492 }
493 
494 
495 static void
texture_storage_error(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,bool dsa)496 texture_storage_error(struct gl_context *ctx, GLuint dims,
497                       struct gl_texture_object *texObj,
498                       GLenum target, GLsizei levels,
499                       GLenum internalformat, GLsizei width,
500                       GLsizei height, GLsizei depth, bool dsa)
501 {
502    texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat,
503                    width, height, depth, dsa, 0, false);
504 }
505 
506 
507 static void
texture_storage_no_error(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,bool dsa)508 texture_storage_no_error(struct gl_context *ctx, GLuint dims,
509                          struct gl_texture_object *texObj,
510                          GLenum target, GLsizei levels,
511                          GLenum internalformat, GLsizei width,
512                          GLsizei height, GLsizei depth, bool dsa)
513 {
514    texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat,
515                    width, height, depth, dsa, 0, true);
516 }
517 
518 
519 /**
520  * Helper used by _mesa_TexStorage1/2/3D().
521  */
522 static void
texstorage_error(GLuint dims,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,const char * caller)523 texstorage_error(GLuint dims, GLenum target, GLsizei levels,
524                  GLenum internalformat, GLsizei width, GLsizei height,
525                  GLsizei depth, const char *caller)
526 {
527    struct gl_texture_object *texObj;
528    GET_CURRENT_CONTEXT(ctx);
529 
530    /* Check target.  This is done here so that texture_storage
531     * can receive unsized formats.
532     */
533    if (!legal_texobj_target(ctx, dims, target)) {
534       _mesa_error(ctx, GL_INVALID_ENUM,
535                   "%s(illegal target=%s)",
536                   caller, _mesa_enum_to_string(target));
537       return;
538    }
539 
540    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
541       _mesa_debug(ctx, "%s %s %d %s %d %d %d\n", caller,
542                   _mesa_enum_to_string(target), levels,
543                   _mesa_enum_to_string(internalformat),
544                   width, height, depth);
545 
546    /* Check the format to make sure it is sized. */
547    if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
548       _mesa_error(ctx, GL_INVALID_ENUM,
549                   "%s(internalformat = %s)", caller,
550                   _mesa_enum_to_string(internalformat));
551       return;
552    }
553 
554    texObj = _mesa_get_current_tex_object(ctx, target);
555    if (!texObj)
556       return;
557 
558    texture_storage_error(ctx, dims, texObj, target, levels,
559                          internalformat, width, height, depth, false);
560 }
561 
562 
563 static void
texstorage_no_error(GLuint dims,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)564 texstorage_no_error(GLuint dims, GLenum target, GLsizei levels,
565                     GLenum internalformat, GLsizei width, GLsizei height,
566                     GLsizei depth)
567 {
568    GET_CURRENT_CONTEXT(ctx);
569 
570    struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target);
571    texture_storage_no_error(ctx, dims, texObj, target, levels,
572                             internalformat, width, height, depth, false);
573 }
574 
575 
576 /**
577  * Helper used by _mesa_TextureStorage1/2/3D().
578  */
579 static void
texturestorage_error(GLuint dims,GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,const char * caller)580 texturestorage_error(GLuint dims, GLuint texture, GLsizei levels,
581                      GLenum internalformat, GLsizei width, GLsizei height,
582                      GLsizei depth, const char *caller)
583 {
584    struct gl_texture_object *texObj;
585    GET_CURRENT_CONTEXT(ctx);
586 
587    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
588       _mesa_debug(ctx, "%s %d %d %s %d %d %d\n",
589                   caller, texture, levels,
590                   _mesa_enum_to_string(internalformat),
591                   width, height, depth);
592 
593    /* Check the format to make sure it is sized. */
594    if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
595       _mesa_error(ctx, GL_INVALID_ENUM,
596                   "%s(internalformat = %s)", caller,
597                   _mesa_enum_to_string(internalformat));
598       return;
599    }
600 
601    texObj = _mesa_lookup_texture_err(ctx, texture, caller);
602    if (!texObj)
603       return;
604 
605    /* Check target.  This is done here so that texture_storage
606     * can receive unsized formats.
607     */
608    if (!legal_texobj_target(ctx, dims, texObj->Target)) {
609       _mesa_error(ctx, GL_INVALID_OPERATION,
610                   "%s(illegal target=%s)", caller,
611                   _mesa_enum_to_string(texObj->Target));
612       return;
613    }
614 
615    texture_storage_error(ctx, dims, texObj, texObj->Target,
616                          levels, internalformat, width, height, depth, true);
617 }
618 
619 
620 static void
texturestorage_no_error(GLuint dims,GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)621 texturestorage_no_error(GLuint dims, GLuint texture, GLsizei levels,
622                         GLenum internalformat, GLsizei width, GLsizei height,
623                         GLsizei depth)
624 {
625    GET_CURRENT_CONTEXT(ctx);
626 
627    struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture);
628    texture_storage_no_error(ctx, dims, texObj, texObj->Target,
629                             levels, internalformat, width, height, depth, true);
630 }
631 
632 
633 void GLAPIENTRY
_mesa_TexStorage1D_no_error(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)634 _mesa_TexStorage1D_no_error(GLenum target, GLsizei levels,
635                             GLenum internalformat, GLsizei width)
636 {
637    texstorage_no_error(1, target, levels, internalformat, width, 1, 1);
638 }
639 
640 
641 void GLAPIENTRY
_mesa_TexStorage1D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)642 _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,
643                    GLsizei width)
644 {
645    texstorage_error(1, target, levels, internalformat, width, 1, 1,
646                     "glTexStorage1D");
647 }
648 
649 
650 void GLAPIENTRY
_mesa_TexStorage2D_no_error(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)651 _mesa_TexStorage2D_no_error(GLenum target, GLsizei levels,
652                             GLenum internalformat, GLsizei width,
653                             GLsizei height)
654 {
655    texstorage_no_error(2, target, levels, internalformat, width, height, 1);
656 }
657 
658 
659 void GLAPIENTRY
_mesa_TexStorage2D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)660 _mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat,
661                    GLsizei width, GLsizei height)
662 {
663    texstorage_error(2, target, levels, internalformat, width, height, 1,
664                     "glTexStorage2D");
665 }
666 
667 
668 void GLAPIENTRY
_mesa_TexStorage3D_no_error(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)669 _mesa_TexStorage3D_no_error(GLenum target, GLsizei levels,
670                             GLenum internalformat, GLsizei width,
671                             GLsizei height, GLsizei depth)
672 {
673    texstorage_no_error(3, target, levels, internalformat, width, height, depth);
674 }
675 
676 
677 void GLAPIENTRY
_mesa_TexStorage3D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)678 _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
679                    GLsizei width, GLsizei height, GLsizei depth)
680 {
681    texstorage_error(3, target, levels, internalformat, width, height, depth,
682                     "glTexStorage3D");
683 }
684 
685 
686 void GLAPIENTRY
_mesa_TextureStorage1D_no_error(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width)687 _mesa_TextureStorage1D_no_error(GLuint texture, GLsizei levels,
688                                 GLenum internalformat, GLsizei width)
689 {
690    texturestorage_no_error(1, texture, levels, internalformat, width, 1, 1);
691 }
692 
693 
694 void GLAPIENTRY
_mesa_TextureStorage1D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width)695 _mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,
696                        GLsizei width)
697 {
698    texturestorage_error(1, texture, levels, internalformat, width, 1, 1,
699                         "glTextureStorage1D");
700 }
701 
702 
703 void GLAPIENTRY
_mesa_TextureStorage2D_no_error(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)704 _mesa_TextureStorage2D_no_error(GLuint texture, GLsizei levels,
705                                 GLenum internalformat,
706                                 GLsizei width, GLsizei height)
707 {
708    texturestorage_no_error(2, texture, levels, internalformat, width, height, 1);
709 }
710 
711 
712 void GLAPIENTRY
_mesa_TextureStorage2D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)713 _mesa_TextureStorage2D(GLuint texture, GLsizei levels,
714                        GLenum internalformat,
715                        GLsizei width, GLsizei height)
716 {
717    texturestorage_error(2, texture, levels, internalformat, width, height, 1,
718                         "glTextureStorage2D");
719 }
720 
721 
722 void GLAPIENTRY
_mesa_TextureStorage3D_no_error(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)723 _mesa_TextureStorage3D_no_error(GLuint texture, GLsizei levels,
724                                 GLenum internalformat, GLsizei width,
725                                 GLsizei height, GLsizei depth)
726 {
727    texturestorage_no_error(3, texture, levels, internalformat, width, height,
728                            depth);
729 }
730 
731 
732 void GLAPIENTRY
_mesa_TextureStorage3D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)733 _mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,
734                        GLsizei width, GLsizei height, GLsizei depth)
735 {
736    texturestorage_error(3, texture, levels, internalformat, width, height, depth,
737                         "glTextureStorage3D");
738 }
739 
740 
741 void GLAPIENTRY
_mesa_TextureStorage1DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)742 _mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels,
743                           GLenum internalformat,
744                           GLsizei width)
745 {
746    GET_CURRENT_CONTEXT(ctx);
747    /* 'texture' must always be initialized, even if the call to
748     * glTextureStorage1DEXT will generate an error.
749     */
750    if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
751                                        "glTextureStorage1DEXT"))
752       return;
753    texturestorage_error(1, texture, levels, internalformat, width, 1, 1,
754                         "glTextureStorage1DEXT");
755 }
756 
757 
758 void GLAPIENTRY
_mesa_TextureStorage2DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)759 _mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels,
760                           GLenum internalformat,
761                           GLsizei width, GLsizei height)
762 {
763    GET_CURRENT_CONTEXT(ctx);
764    /* 'texture' must always be initialized, even if the call to
765     * glTextureStorage2DEXT will generate an error.
766     */
767    if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
768                                        "glTextureStorage2DEXT"))
769       return;
770    texturestorage_error(2, texture, levels, internalformat, width, height, 1,
771                         "glTextureStorage2DEXT");
772 }
773 
774 
775 void GLAPIENTRY
_mesa_TextureStorage3DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)776 _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
777                           GLenum internalformat,
778                           GLsizei width, GLsizei height, GLsizei depth)
779 {
780    GET_CURRENT_CONTEXT(ctx);
781    /* 'texture' must always be initialized, even if the call to
782     * glTextureStorage3DEXT will generate an error.
783     */
784    if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
785                                        "glTextureStorage3DEXT"))
786       return;
787    texturestorage_error(3, texture, levels, internalformat, width, height, depth,
788                         "glTextureStorage3DEXT");
789 }
790 
791 
792 void
_mesa_texture_storage_memory(struct gl_context * ctx,GLuint dims,struct gl_texture_object * texObj,struct gl_memory_object * memObj,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLuint64 offset,bool dsa)793 _mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims,
794                              struct gl_texture_object *texObj,
795                              struct gl_memory_object *memObj,
796                              GLenum target, GLsizei levels,
797                              GLenum internalformat, GLsizei width,
798                              GLsizei height, GLsizei depth,
799                              GLuint64 offset, bool dsa)
800 {
801    assert(memObj);
802 
803    texture_storage(ctx, dims, texObj, memObj, target, levels, internalformat,
804                    width, height, depth, offset, dsa, false);
805 }
806