• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "imports.h"
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          }
449       }
450 
451       assert(levels > 0);
452       assert(width > 0);
453       assert(height > 0);
454       assert(depth > 0);
455 
456       if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth,
457                                      internalformat, texFormat)) {
458          return;
459       }
460 
461       /* Setup the backing memory */
462       if (memObj) {
463          if (!ctx->Driver.SetTextureStorageForMemoryObject(ctx, texObj, memObj,
464                                                            levels,
465                                                            width, height, depth,
466                                                            offset)) {
467 
468             clear_texture_fields(ctx, texObj);
469             return;
470          }
471       }
472       else {
473          if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
474                                               width, height, depth)) {
475             /* Reset the texture images' info to zeros.
476              * Strictly speaking, we probably don't have to do this since
477              * generating GL_OUT_OF_MEMORY can leave things in an undefined
478              * state but this puts things in a consistent state.
479              */
480             clear_texture_fields(ctx, texObj);
481             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
482                         suffix, dims);
483             return;
484          }
485       }
486 
487       _mesa_set_texture_view_state(ctx, texObj, target, levels);
488 
489       update_fbo_texture(ctx, texObj);
490    }
491 }
492 
493 
494 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)495 texture_storage_error(struct gl_context *ctx, GLuint dims,
496                       struct gl_texture_object *texObj,
497                       GLenum target, GLsizei levels,
498                       GLenum internalformat, GLsizei width,
499                       GLsizei height, GLsizei depth, bool dsa)
500 {
501    texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat,
502                    width, height, depth, dsa, 0, false);
503 }
504 
505 
506 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)507 texture_storage_no_error(struct gl_context *ctx, GLuint dims,
508                          struct gl_texture_object *texObj,
509                          GLenum target, GLsizei levels,
510                          GLenum internalformat, GLsizei width,
511                          GLsizei height, GLsizei depth, bool dsa)
512 {
513    texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat,
514                    width, height, depth, dsa, 0, true);
515 }
516 
517 
518 /**
519  * Helper used by _mesa_TexStorage1/2/3D().
520  */
521 static void
texstorage_error(GLuint dims,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,const char * caller)522 texstorage_error(GLuint dims, GLenum target, GLsizei levels,
523                  GLenum internalformat, GLsizei width, GLsizei height,
524                  GLsizei depth, const char *caller)
525 {
526    struct gl_texture_object *texObj;
527    GET_CURRENT_CONTEXT(ctx);
528 
529    /* Check target.  This is done here so that texture_storage
530     * can receive unsized formats.
531     */
532    if (!legal_texobj_target(ctx, dims, target)) {
533       _mesa_error(ctx, GL_INVALID_ENUM,
534                   "%s(illegal target=%s)",
535                   caller, _mesa_enum_to_string(target));
536       return;
537    }
538 
539    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
540       _mesa_debug(ctx, "%s %s %d %s %d %d %d\n", caller,
541                   _mesa_enum_to_string(target), levels,
542                   _mesa_enum_to_string(internalformat),
543                   width, height, depth);
544 
545    /* Check the format to make sure it is sized. */
546    if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
547       _mesa_error(ctx, GL_INVALID_ENUM,
548                   "%s(internalformat = %s)", caller,
549                   _mesa_enum_to_string(internalformat));
550       return;
551    }
552 
553    texObj = _mesa_get_current_tex_object(ctx, target);
554    if (!texObj)
555       return;
556 
557    texture_storage_error(ctx, dims, texObj, target, levels,
558                          internalformat, width, height, depth, false);
559 }
560 
561 
562 static void
texstorage_no_error(GLuint dims,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)563 texstorage_no_error(GLuint dims, GLenum target, GLsizei levels,
564                     GLenum internalformat, GLsizei width, GLsizei height,
565                     GLsizei depth)
566 {
567    GET_CURRENT_CONTEXT(ctx);
568 
569    struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target);
570    texture_storage_no_error(ctx, dims, texObj, target, levels,
571                             internalformat, width, height, depth, false);
572 }
573 
574 
575 /**
576  * Helper used by _mesa_TextureStorage1/2/3D().
577  */
578 static void
texturestorage_error(GLuint dims,GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,const char * caller)579 texturestorage_error(GLuint dims, GLuint texture, GLsizei levels,
580                      GLenum internalformat, GLsizei width, GLsizei height,
581                      GLsizei depth, const char *caller)
582 {
583    struct gl_texture_object *texObj;
584    GET_CURRENT_CONTEXT(ctx);
585 
586    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
587       _mesa_debug(ctx, "%s %d %d %s %d %d %d\n",
588                   caller, texture, levels,
589                   _mesa_enum_to_string(internalformat),
590                   width, height, depth);
591 
592    /* Check the format to make sure it is sized. */
593    if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
594       _mesa_error(ctx, GL_INVALID_ENUM,
595                   "%s(internalformat = %s)", caller,
596                   _mesa_enum_to_string(internalformat));
597       return;
598    }
599 
600    texObj = _mesa_lookup_texture_err(ctx, texture, caller);
601    if (!texObj)
602       return;
603 
604    /* Check target.  This is done here so that texture_storage
605     * can receive unsized formats.
606     */
607    if (!legal_texobj_target(ctx, dims, texObj->Target)) {
608       _mesa_error(ctx, GL_INVALID_OPERATION,
609                   "%s(illegal target=%s)", caller,
610                   _mesa_enum_to_string(texObj->Target));
611       return;
612    }
613 
614    texture_storage_error(ctx, dims, texObj, texObj->Target,
615                          levels, internalformat, width, height, depth, true);
616 }
617 
618 
619 static void
texturestorage_no_error(GLuint dims,GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)620 texturestorage_no_error(GLuint dims, GLuint texture, GLsizei levels,
621                         GLenum internalformat, GLsizei width, GLsizei height,
622                         GLsizei depth)
623 {
624    GET_CURRENT_CONTEXT(ctx);
625 
626    struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture);
627    texture_storage_no_error(ctx, dims, texObj, texObj->Target,
628                             levels, internalformat, width, height, depth, true);
629 }
630 
631 
632 void GLAPIENTRY
_mesa_TexStorage1D_no_error(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)633 _mesa_TexStorage1D_no_error(GLenum target, GLsizei levels,
634                             GLenum internalformat, GLsizei width)
635 {
636    texstorage_no_error(1, target, levels, internalformat, width, 1, 1);
637 }
638 
639 
640 void GLAPIENTRY
_mesa_TexStorage1D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)641 _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,
642                    GLsizei width)
643 {
644    texstorage_error(1, target, levels, internalformat, width, 1, 1,
645                     "glTexStorage1D");
646 }
647 
648 
649 void GLAPIENTRY
_mesa_TexStorage2D_no_error(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)650 _mesa_TexStorage2D_no_error(GLenum target, GLsizei levels,
651                             GLenum internalformat, GLsizei width,
652                             GLsizei height)
653 {
654    texstorage_no_error(2, target, levels, internalformat, width, height, 1);
655 }
656 
657 
658 void GLAPIENTRY
_mesa_TexStorage2D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)659 _mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat,
660                    GLsizei width, GLsizei height)
661 {
662    texstorage_error(2, target, levels, internalformat, width, height, 1,
663                     "glTexStorage2D");
664 }
665 
666 
667 void GLAPIENTRY
_mesa_TexStorage3D_no_error(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)668 _mesa_TexStorage3D_no_error(GLenum target, GLsizei levels,
669                             GLenum internalformat, GLsizei width,
670                             GLsizei height, GLsizei depth)
671 {
672    texstorage_no_error(3, target, levels, internalformat, width, height, depth);
673 }
674 
675 
676 void GLAPIENTRY
_mesa_TexStorage3D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)677 _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
678                    GLsizei width, GLsizei height, GLsizei depth)
679 {
680    texstorage_error(3, target, levels, internalformat, width, height, depth,
681                     "glTexStorage3D");
682 }
683 
684 
685 void GLAPIENTRY
_mesa_TextureStorage1D_no_error(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width)686 _mesa_TextureStorage1D_no_error(GLuint texture, GLsizei levels,
687                                 GLenum internalformat, GLsizei width)
688 {
689    texturestorage_no_error(1, texture, levels, internalformat, width, 1, 1);
690 }
691 
692 
693 void GLAPIENTRY
_mesa_TextureStorage1D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width)694 _mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,
695                        GLsizei width)
696 {
697    texturestorage_error(1, texture, levels, internalformat, width, 1, 1,
698                         "glTextureStorage1D");
699 }
700 
701 
702 void GLAPIENTRY
_mesa_TextureStorage2D_no_error(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)703 _mesa_TextureStorage2D_no_error(GLuint texture, GLsizei levels,
704                                 GLenum internalformat,
705                                 GLsizei width, GLsizei height)
706 {
707    texturestorage_no_error(2, texture, levels, internalformat, width, height, 1);
708 }
709 
710 
711 void GLAPIENTRY
_mesa_TextureStorage2D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)712 _mesa_TextureStorage2D(GLuint texture, GLsizei levels,
713                        GLenum internalformat,
714                        GLsizei width, GLsizei height)
715 {
716    texturestorage_error(2, texture, levels, internalformat, width, height, 1,
717                         "glTextureStorage2D");
718 }
719 
720 
721 void GLAPIENTRY
_mesa_TextureStorage3D_no_error(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)722 _mesa_TextureStorage3D_no_error(GLuint texture, GLsizei levels,
723                                 GLenum internalformat, GLsizei width,
724                                 GLsizei height, GLsizei depth)
725 {
726    texturestorage_no_error(3, texture, levels, internalformat, width, height,
727                            depth);
728 }
729 
730 
731 void GLAPIENTRY
_mesa_TextureStorage3D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)732 _mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,
733                        GLsizei width, GLsizei height, GLsizei depth)
734 {
735    texturestorage_error(3, texture, levels, internalformat, width, height, depth,
736                         "glTextureStorage3D");
737 }
738 
739 
740 /*
741  * Note: we don't support GL_EXT_direct_state_access and the spec says
742  * we don't need the following functions.  However, glew checks for the
743  * presence of all six functions and will say that GL_ARB_texture_storage
744  * is not supported if these functions are missing.
745  */
746 
747 
748 void GLAPIENTRY
_mesa_TextureStorage1DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)749 _mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels,
750                           GLenum internalformat,
751                           GLsizei width)
752 {
753    GET_CURRENT_CONTEXT(ctx);
754 
755    (void) texture;
756    (void) target;
757    (void) levels;
758    (void) internalformat;
759    (void) width;
760 
761    _mesa_error(ctx, GL_INVALID_OPERATION,
762                "glTextureStorage1DEXT not supported");
763 }
764 
765 
766 void GLAPIENTRY
_mesa_TextureStorage2DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)767 _mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels,
768                           GLenum internalformat,
769                           GLsizei width, GLsizei height)
770 {
771    GET_CURRENT_CONTEXT(ctx);
772 
773    (void) texture;
774    (void) target;
775    (void) levels;
776    (void) internalformat;
777    (void) width;
778    (void) height;
779 
780    _mesa_error(ctx, GL_INVALID_OPERATION,
781                "glTextureStorage2DEXT not supported");
782 }
783 
784 
785 void GLAPIENTRY
_mesa_TextureStorage3DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)786 _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
787                           GLenum internalformat,
788                           GLsizei width, GLsizei height, GLsizei depth)
789 {
790    GET_CURRENT_CONTEXT(ctx);
791 
792    (void) texture;
793    (void) target;
794    (void) levels;
795    (void) internalformat;
796    (void) width;
797    (void) height;
798    (void) depth;
799 
800    _mesa_error(ctx, GL_INVALID_OPERATION,
801                "glTextureStorage3DEXT not supported");
802 }
803 
804 
805 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)806 _mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims,
807                              struct gl_texture_object *texObj,
808                              struct gl_memory_object *memObj,
809                              GLenum target, GLsizei levels,
810                              GLenum internalformat, GLsizei width,
811                              GLsizei height, GLsizei depth,
812                              GLuint64 offset, bool dsa)
813 {
814    assert(memObj);
815 
816    texture_storage(ctx, dims, texObj, memObj, target, levels, internalformat,
817                    width, height, depth, offset, dsa, false);
818 }
819