• 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,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                         GLuint dims, GLenum target,
308                         GLsizei levels, GLenum internalformat,
309                         GLsizei width, GLsizei height, GLsizei depth,
310                         bool dsa)
311 {
312    const char* suffix = dsa ? "ture" : "";
313 
314    /* Legal format checking has been moved to texstorage and texturestorage in
315     * order to allow meta functions to use legacy formats. */
316 
317    /* size check */
318    if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
319       _mesa_error(ctx, GL_INVALID_VALUE,
320                   "glTex%sStorage%uD(width, height or depth < 1)",
321                   suffix, dims);
322       return GL_TRUE;
323    }
324 
325    if (_mesa_is_compressed_format(ctx, internalformat)) {
326       GLenum err;
327       if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) {
328          _mesa_error(ctx, err,
329                   "glTex%sStorage%dD(internalformat = %s)", suffix, dims,
330                   _mesa_enum_to_string(internalformat));
331          return GL_TRUE;
332       }
333    }
334 
335    /* levels check */
336    if (levels < 1) {
337       _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)",
338                   suffix, dims);
339       return GL_TRUE;
340    }
341 
342    /* check levels against maximum (note different error than above) */
343    if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) {
344       _mesa_error(ctx, GL_INVALID_OPERATION,
345                   "glTex%sStorage%uD(levels too large)",
346                   suffix, dims);
347       return GL_TRUE;
348    }
349 
350    /* check levels against width/height/depth */
351    if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) {
352       _mesa_error(ctx, GL_INVALID_OPERATION,
353                   "glTex%sStorage%uD(too many levels"
354                   " for max texture dimension)",
355                   suffix, dims);
356       return GL_TRUE;
357    }
358 
359    /* non-default texture object check */
360    if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) {
361       _mesa_error(ctx, GL_INVALID_OPERATION,
362                   "glTex%sStorage%uD(texture object 0)",
363                   suffix, dims);
364       return GL_TRUE;
365    }
366 
367    /* Check if texObj->Immutable is set */
368    if (!_mesa_is_proxy_texture(target) && texObj->Immutable) {
369       _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)",
370                   suffix, dims);
371       return GL_TRUE;
372    }
373 
374    /* additional checks for depth textures */
375    if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) {
376       _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(bad target for texture)",
377                   suffix, dims);
378       return GL_TRUE;
379    }
380 
381    return GL_FALSE;
382 }
383 
384 
385 /**
386  * Helper that does the storage allocation for _mesa_TexStorage1/2/3D()
387  * and _mesa_TextureStorage1/2/3D().
388  */
389 void
_mesa_texture_storage(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)390 _mesa_texture_storage(struct gl_context *ctx, GLuint dims,
391                       struct gl_texture_object *texObj,
392                       GLenum target, GLsizei levels,
393                       GLenum internalformat, GLsizei width,
394                       GLsizei height, GLsizei depth, bool dsa)
395 {
396    GLboolean sizeOK, dimensionsOK;
397    mesa_format texFormat;
398    const char* suffix = dsa ? "ture" : "";
399 
400    assert(texObj);
401 
402    if (tex_storage_error_check(ctx, texObj, dims, target, levels,
403                                internalformat, width, height, depth, dsa)) {
404       return; /* error was recorded */
405    }
406 
407    texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
408                                            internalformat, GL_NONE, GL_NONE);
409    assert(texFormat != MESA_FORMAT_NONE);
410 
411    /* check that width, height, depth are legal for the mipmap level */
412    dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
413                                                   width, height, depth, 0);
414 
415    sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, levels, 0, texFormat,
416                                           1, width, height, depth);
417 
418    if (_mesa_is_proxy_texture(target)) {
419       if (dimensionsOK && sizeOK) {
420          initialize_texture_fields(ctx, texObj, levels, width, height, depth,
421                                    internalformat, texFormat);
422       }
423       else {
424          /* clear all image fields for [levels] */
425          clear_texture_fields(ctx, texObj);
426       }
427    }
428    else {
429       if (!dimensionsOK) {
430          _mesa_error(ctx, GL_INVALID_VALUE,
431                      "glTex%sStorage%uD(invalid width, height or depth)",
432                      suffix, dims);
433          return;
434       }
435 
436       if (!sizeOK) {
437          _mesa_error(ctx, GL_OUT_OF_MEMORY,
438                      "glTex%sStorage%uD(texture too large)",
439                      suffix, dims);
440       }
441 
442       assert(levels > 0);
443       assert(width > 0);
444       assert(height > 0);
445       assert(depth > 0);
446 
447       if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth,
448                                      internalformat, texFormat)) {
449          return;
450       }
451 
452       /* Do actual texture memory allocation */
453       if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
454                                            width, height, depth)) {
455          /* Reset the texture images' info to zeros.
456           * Strictly speaking, we probably don't have to do this since
457           * generating GL_OUT_OF_MEMORY can leave things in an undefined
458           * state but this puts things in a consistent state.
459           */
460          clear_texture_fields(ctx, texObj);
461          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
462                      suffix, dims);
463          return;
464       }
465 
466       _mesa_set_texture_view_state(ctx, texObj, target, levels);
467 
468       update_fbo_texture(ctx, texObj);
469    }
470 }
471 
472 
473 /**
474  * Helper used by _mesa_TexStorage1/2/3D().
475  */
476 static void
texstorage(GLuint dims,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)477 texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
478            GLsizei width, GLsizei height, GLsizei depth)
479 {
480    struct gl_texture_object *texObj;
481    GET_CURRENT_CONTEXT(ctx);
482 
483    /* Check target.  This is done here so that _mesa_texture_storage
484     * can receive unsized formats.
485     */
486    if (!legal_texobj_target(ctx, dims, target)) {
487       _mesa_error(ctx, GL_INVALID_ENUM,
488                   "glTexStorage%uD(illegal target=%s)",
489                   dims, _mesa_enum_to_string(target));
490       return;
491    }
492 
493    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
494       _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n",
495                   dims,
496                   _mesa_enum_to_string(target), levels,
497                   _mesa_enum_to_string(internalformat),
498                   width, height, depth);
499 
500    /* Check the format to make sure it is sized. */
501    if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
502       _mesa_error(ctx, GL_INVALID_ENUM,
503                   "glTexStorage%uD(internalformat = %s)", dims,
504                   _mesa_enum_to_string(internalformat));
505       return;
506    }
507 
508    texObj = _mesa_get_current_tex_object(ctx, target);
509    if (!texObj)
510       return;
511 
512    _mesa_texture_storage(ctx, dims, texObj, target, levels,
513                          internalformat, width, height, depth, false);
514 }
515 
516 
517 /**
518  * Helper used by _mesa_TextureStorage1/2/3D().
519  */
520 static void
texturestorage(GLuint dims,GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)521 texturestorage(GLuint dims, GLuint texture, GLsizei levels,
522                GLenum internalformat, GLsizei width, GLsizei height,
523                GLsizei depth)
524 {
525    struct gl_texture_object *texObj;
526    GET_CURRENT_CONTEXT(ctx);
527 
528    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
529       _mesa_debug(ctx, "glTextureStorage%uD %d %d %s %d %d %d\n",
530                   dims, texture, levels,
531                   _mesa_enum_to_string(internalformat),
532                   width, height, depth);
533 
534    /* Check the format to make sure it is sized. */
535    if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
536       _mesa_error(ctx, GL_INVALID_ENUM,
537                   "glTextureStorage%uD(internalformat = %s)", dims,
538                   _mesa_enum_to_string(internalformat));
539       return;
540    }
541 
542    /* Get the texture object by Name. */
543    texObj = _mesa_lookup_texture(ctx, texture);
544    if (!texObj) {
545       _mesa_error(ctx, GL_INVALID_OPERATION,
546                   "glTextureStorage%uD(texture = %d)", dims, texture);
547       return;
548    }
549 
550    /* Check target.  This is done here so that _mesa_texture_storage
551     * can receive unsized formats.
552     */
553    if (!legal_texobj_target(ctx, dims, texObj->Target)) {
554       _mesa_error(ctx, GL_INVALID_ENUM,
555                   "glTextureStorage%uD(illegal target=%s)",
556                   dims, _mesa_enum_to_string(texObj->Target));
557       return;
558    }
559 
560    _mesa_texture_storage(ctx, dims, texObj, texObj->Target,
561                          levels, internalformat, width, height, depth, true);
562 }
563 
564 
565 void GLAPIENTRY
_mesa_TexStorage1D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)566 _mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,
567                    GLsizei width)
568 {
569    texstorage(1, target, levels, internalformat, width, 1, 1);
570 }
571 
572 
573 void GLAPIENTRY
_mesa_TexStorage2D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)574 _mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat,
575                    GLsizei width, GLsizei height)
576 {
577    texstorage(2, target, levels, internalformat, width, height, 1);
578 }
579 
580 
581 void GLAPIENTRY
_mesa_TexStorage3D(GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)582 _mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
583                    GLsizei width, GLsizei height, GLsizei depth)
584 {
585    texstorage(3, target, levels, internalformat, width, height, depth);
586 }
587 
588 
589 void GLAPIENTRY
_mesa_TextureStorage1D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width)590 _mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,
591                        GLsizei width)
592 {
593    texturestorage(1, texture, levels, internalformat, width, 1, 1);
594 }
595 
596 
597 void GLAPIENTRY
_mesa_TextureStorage2D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)598 _mesa_TextureStorage2D(GLuint texture, GLsizei levels,
599                        GLenum internalformat,
600                        GLsizei width, GLsizei height)
601 {
602    texturestorage(2, texture, levels, internalformat, width, height, 1);
603 }
604 
605 
606 void GLAPIENTRY
_mesa_TextureStorage3D(GLuint texture,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)607 _mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,
608                        GLsizei width, GLsizei height, GLsizei depth)
609 {
610    texturestorage(3, texture, levels, internalformat, width, height, depth);
611 }
612 
613 
614 /*
615  * Note: we don't support GL_EXT_direct_state_access and the spec says
616  * we don't need the following functions.  However, glew checks for the
617  * presence of all six functions and will say that GL_ARB_texture_storage
618  * is not supported if these functions are missing.
619  */
620 
621 
622 void GLAPIENTRY
_mesa_TextureStorage1DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)623 _mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels,
624                           GLenum internalformat,
625                           GLsizei width)
626 {
627    GET_CURRENT_CONTEXT(ctx);
628 
629    (void) texture;
630    (void) target;
631    (void) levels;
632    (void) internalformat;
633    (void) width;
634 
635    _mesa_error(ctx, GL_INVALID_OPERATION,
636                "glTextureStorage1DEXT not supported");
637 }
638 
639 
640 void GLAPIENTRY
_mesa_TextureStorage2DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)641 _mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels,
642                           GLenum internalformat,
643                           GLsizei width, GLsizei height)
644 {
645    GET_CURRENT_CONTEXT(ctx);
646 
647    (void) texture;
648    (void) target;
649    (void) levels;
650    (void) internalformat;
651    (void) width;
652    (void) height;
653 
654    _mesa_error(ctx, GL_INVALID_OPERATION,
655                "glTextureStorage2DEXT not supported");
656 }
657 
658 
659 void GLAPIENTRY
_mesa_TextureStorage3DEXT(GLuint texture,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)660 _mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
661                           GLenum internalformat,
662                           GLsizei width, GLsizei height, GLsizei depth)
663 {
664    GET_CURRENT_CONTEXT(ctx);
665 
666    (void) texture;
667    (void) target;
668    (void) levels;
669    (void) internalformat;
670    (void) width;
671    (void) height;
672    (void) depth;
673 
674    _mesa_error(ctx, GL_INVALID_OPERATION,
675                "glTextureStorage3DEXT not supported");
676 }
677