Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5564 serge 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
/**
27
 * \file texstorage.c
28
 * GL_ARB_texture_storage functions
29
 */
30
 
31
 
32
 
33
#include "glheader.h"
34
#include "context.h"
35
#include "enums.h"
36
#include "imports.h"
37
#include "macros.h"
38
#include "teximage.h"
39
#include "texobj.h"
40
#include "mipmap.h"
41
#include "texstorage.h"
42
#include "textureview.h"
43
#include "mtypes.h"
44
#include "glformats.h"
45
#include "hash.h"
46
 
47
 
48
/**
49
 * Check if the given texture target is a legal texture object target
50
 * for a glTexStorage() command.
51
 * This is a bit different than legal_teximage_target() when it comes
52
 * to cube maps.
53
 */
54
static GLboolean
55
legal_texobj_target(struct gl_context *ctx, GLuint dims, GLenum target)
56
{
57
   if (_mesa_is_gles3(ctx)
58
       && target != GL_TEXTURE_2D
59
       && target != GL_TEXTURE_CUBE_MAP
60
       && target != GL_TEXTURE_3D
61
       && target != GL_TEXTURE_2D_ARRAY)
62
      return GL_FALSE;
63
 
64
   switch (dims) {
65
   case 1:
66
      switch (target) {
67
      case GL_TEXTURE_1D:
68
      case GL_PROXY_TEXTURE_1D:
69
         return GL_TRUE;
70
      default:
71
         return GL_FALSE;
72
      }
73
   case 2:
74
      switch (target) {
75
      case GL_TEXTURE_2D:
76
      case GL_PROXY_TEXTURE_2D:
77
         return GL_TRUE;
78
      case GL_TEXTURE_CUBE_MAP:
79
      case GL_PROXY_TEXTURE_CUBE_MAP:
80
         return ctx->Extensions.ARB_texture_cube_map;
81
      case GL_TEXTURE_RECTANGLE:
82
      case GL_PROXY_TEXTURE_RECTANGLE:
83
         return ctx->Extensions.NV_texture_rectangle;
84
      case GL_TEXTURE_1D_ARRAY:
85
      case GL_PROXY_TEXTURE_1D_ARRAY:
86
         return ctx->Extensions.EXT_texture_array;
87
      default:
88
         return GL_FALSE;
89
      }
90
   case 3:
91
      switch (target) {
92
      case GL_TEXTURE_3D:
93
      case GL_PROXY_TEXTURE_3D:
94
         return GL_TRUE;
95
      case GL_TEXTURE_2D_ARRAY:
96
      case GL_PROXY_TEXTURE_2D_ARRAY:
97
         return ctx->Extensions.EXT_texture_array;
98
      case GL_TEXTURE_CUBE_MAP_ARRAY:
99
      case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
100
         return ctx->Extensions.ARB_texture_cube_map_array;
101
      default:
102
         return GL_FALSE;
103
      }
104
   default:
105
      _mesa_problem(ctx, "invalid dims=%u in legal_texobj_target()", dims);
106
      return GL_FALSE;
107
   }
108
}
109
 
110
 
111
/** Helper to get a particular texture image in a texture object */
112
static struct gl_texture_image *
113
get_tex_image(struct gl_context *ctx,
114
              struct gl_texture_object *texObj,
115
              GLuint face, GLuint level)
116
{
117
   const GLenum faceTarget =
118
      (texObj->Target == GL_TEXTURE_CUBE_MAP ||
119
       texObj->Target == GL_PROXY_TEXTURE_CUBE_MAP)
120
      ? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : texObj->Target;
121
   return _mesa_get_tex_image(ctx, texObj, faceTarget, level);
122
}
123
 
124
 
125
 
126
static GLboolean
127
initialize_texture_fields(struct gl_context *ctx,
128
                          struct gl_texture_object *texObj,
129
                          GLint levels,
130
                          GLsizei width, GLsizei height, GLsizei depth,
131
                          GLenum internalFormat, mesa_format texFormat)
132
{
133
   const GLenum target = texObj->Target;
134
   const GLuint numFaces = _mesa_num_tex_faces(target);
135
   GLint level, levelWidth = width, levelHeight = height, levelDepth = depth;
136
   GLuint face;
137
 
138
   /* Set up all the texture object's gl_texture_images */
139
   for (level = 0; level < levels; level++) {
140
      for (face = 0; face < numFaces; face++) {
141
         struct gl_texture_image *texImage =
142
            get_tex_image(ctx, texObj, face, level);
143
 
144
	 if (!texImage) {
145
	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
146
            return GL_FALSE;
147
	 }
148
 
149
         _mesa_init_teximage_fields(ctx, texImage,
150
                                    levelWidth, levelHeight, levelDepth,
151
                                    0, internalFormat, texFormat);
152
      }
153
 
154
      _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth,
155
                                   &levelWidth, &levelHeight, &levelDepth);
156
   }
157
   return GL_TRUE;
158
}
159
 
160
 
161
/**
162
 * Clear all fields of texture object to zeros.  Used for proxy texture tests
163
 * and to clean up when a texture memory allocation fails.
164
 */
165
static void
166
clear_texture_fields(struct gl_context *ctx,
167
                     struct gl_texture_object *texObj)
168
{
169
   const GLenum target = texObj->Target;
170
   const GLuint numFaces = _mesa_num_tex_faces(target);
171
   GLint level;
172
   GLuint face;
173
 
174
   for (level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) {
175
      for (face = 0; face < numFaces; face++) {
176
         struct gl_texture_image *texImage =
177
            get_tex_image(ctx, texObj, face, level);
178
 
179
	 if (!texImage) {
180
	    _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
181
            return;
182
	 }
183
 
184
         _mesa_init_teximage_fields(ctx, texImage,
185
                                    0, 0, 0, 0, /* w, h, d, border */
186
                                    GL_NONE, MESA_FORMAT_NONE);
187
      }
188
   }
189
}
190
 
191
 
192
GLboolean
193
_mesa_is_legal_tex_storage_format(struct gl_context *ctx, GLenum internalformat)
194
{
195
   /* check internal format - note that only sized formats are allowed */
196
   switch (internalformat) {
197
   case GL_ALPHA:
198
   case GL_LUMINANCE:
199
   case GL_LUMINANCE_ALPHA:
200
   case GL_INTENSITY:
201
   case GL_RED:
202
   case GL_RG:
203
   case GL_RGB:
204
   case GL_RGBA:
205
   case GL_BGRA:
206
   case GL_DEPTH_COMPONENT:
207
   case GL_DEPTH_STENCIL:
208
   case GL_COMPRESSED_ALPHA:
209
   case GL_COMPRESSED_LUMINANCE_ALPHA:
210
   case GL_COMPRESSED_LUMINANCE:
211
   case GL_COMPRESSED_INTENSITY:
212
   case GL_COMPRESSED_RGB:
213
   case GL_COMPRESSED_RGBA:
214
   case GL_COMPRESSED_SRGB:
215
   case GL_COMPRESSED_SRGB_ALPHA:
216
   case GL_COMPRESSED_SLUMINANCE:
217
   case GL_COMPRESSED_SLUMINANCE_ALPHA:
218
   case GL_RED_INTEGER:
219
   case GL_GREEN_INTEGER:
220
   case GL_BLUE_INTEGER:
221
   case GL_ALPHA_INTEGER:
222
   case GL_RGB_INTEGER:
223
   case GL_RGBA_INTEGER:
224
   case GL_BGR_INTEGER:
225
   case GL_BGRA_INTEGER:
226
   case GL_LUMINANCE_INTEGER_EXT:
227
   case GL_LUMINANCE_ALPHA_INTEGER_EXT:
228
      /* these unsized formats are illegal */
229
      return GL_FALSE;
230
   default:
231
      return _mesa_base_tex_format(ctx, internalformat) > 0;
232
   }
233
}
234
 
235
/**
236
 * Default ctx->Driver.AllocTextureStorage() handler.
237
 *
238
 * The driver can override this with a more specific implementation if it
239
 * desires, but this can be used to get the texture images allocated using the
240
 * usual texture image handling code.  The immutability of
241
 * GL_ARB_texture_storage texture layouts is handled by texObj->Immutable
242
 * checks at glTexImage* time.
243
 */
244
GLboolean
245
_mesa_AllocTextureStorage_sw(struct gl_context *ctx,
246
                             struct gl_texture_object *texObj,
247
                             GLsizei levels, GLsizei width,
248
                             GLsizei height, GLsizei depth)
249
{
250
   const int numFaces = _mesa_num_tex_faces(texObj->Target);
251
   int face;
252
   int level;
253
 
254
   (void) width;
255
   (void) height;
256
   (void) depth;
257
 
258
   for (face = 0; face < numFaces; face++) {
259
      for (level = 0; level < levels; level++) {
260
         struct gl_texture_image *const texImage = texObj->Image[face][level];
261
         if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage))
262
            return GL_FALSE;
263
      }
264
   }
265
 
266
   return GL_TRUE;
267
}
268
 
269
 
270
/**
271
 * Do error checking for calls to glTexStorage1/2/3D().
272
 * If an error is found, record it with _mesa_error(), unless the target
273
 * is a proxy texture.
274
 * \return GL_TRUE if any error, GL_FALSE otherwise.
275
 */
276
static GLboolean
277
tex_storage_error_check(struct gl_context *ctx,
278
                        struct gl_texture_object *texObj,
279
                        GLuint dims, GLenum target,
280
                        GLsizei levels, GLenum internalformat,
281
                        GLsizei width, GLsizei height, GLsizei depth,
282
                        bool dsa)
283
{
284
   const char* suffix = dsa ? "ture" : "";
285
 
286
   /* Legal format checking has been moved to texstorage and texturestorage in
287
    * order to allow meta functions to use legacy formats. */
288
 
289
   /* size check */
290
   if (width < 1 || height < 1 || depth < 1) {
291
      _mesa_error(ctx, GL_INVALID_VALUE,
292
                  "glTex%sStorage%uD(width, height or depth < 1)",
293
                  suffix, dims);
294
      return GL_TRUE;
295
   }
296
 
297
   /* From section 3.8.6, page 146 of OpenGL ES 3.0 spec:
298
    *
299
    *    "The ETC2/EAC texture compression algorithm supports only
300
    *     two-dimensional images. If internalformat is an ETC2/EAC format,
301
    *     CompressedTexImage3D will generate an INVALID_OPERATION error if
302
    *     target is not TEXTURE_2D_ARRAY."
303
    *
304
    * This should also be applicable for glTexStorage3D().
305
    */
306
   if (_mesa_is_compressed_format(ctx, internalformat)
307
       && !_mesa_target_can_be_compressed(ctx, target, internalformat)) {
308
      _mesa_error(ctx, _mesa_is_desktop_gl(ctx)?
309
                  GL_INVALID_ENUM : GL_INVALID_OPERATION,
310
                  "glTex%sStorage%dD(internalformat = %s)", suffix, dims,
311
                  _mesa_lookup_enum_by_nr(internalformat));
312
   }
313
 
314
   /* levels check */
315
   if (levels < 1) {
316
      _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)",
317
                  suffix, dims);
318
      return GL_TRUE;
319
   }
320
 
321
   /* check levels against maximum (note different error than above) */
322
   if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) {
323
      _mesa_error(ctx, GL_INVALID_OPERATION,
324
                  "glTex%sStorage%uD(levels too large)",
325
                  suffix, dims);
326
      return GL_TRUE;
327
   }
328
 
329
   /* check levels against width/height/depth */
330
   if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) {
331
      _mesa_error(ctx, GL_INVALID_OPERATION,
332
                  "glTex%sStorage%uD(too many levels"
333
                  " for max texture dimension)",
334
                  suffix, dims);
335
      return GL_TRUE;
336
   }
337
 
338
   /* non-default texture object check */
339
   if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) {
340
      _mesa_error(ctx, GL_INVALID_OPERATION,
341
                  "glTex%sStorage%uD(texture object 0)",
342
                  suffix, dims);
343
      return GL_TRUE;
344
   }
345
 
346
   /* Check if texObj->Immutable is set */
347
   if (!_mesa_is_proxy_texture(target) && texObj->Immutable) {
348
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)",
349
                  suffix, dims);
350
      return GL_TRUE;
351
   }
352
 
353
   /* additional checks for depth textures */
354
   if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat,
355
                                                   dims, dsa ?
356
                                                   "glTextureStorage" :
357
                                                   "glTexStorage"))
358
      return GL_TRUE;
359
 
360
   return GL_FALSE;
361
}
362
 
363
 
364
/**
365
 * Helper that does the storage allocation for _mesa_TexStorage1/2/3D()
366
 * and _mesa_TextureStorage1/2/3D().
367
 */
368
void
369
_mesa_texture_storage(struct gl_context *ctx, GLuint dims,
370
                      struct gl_texture_object *texObj,
371
                      GLenum target, GLsizei levels,
372
                      GLenum internalformat, GLsizei width,
373
                      GLsizei height, GLsizei depth, bool dsa)
374
{
375
   GLboolean sizeOK, dimensionsOK;
376
   mesa_format texFormat;
377
   const char* suffix = dsa ? "ture" : "";
378
 
379
   assert(texObj);
380
 
381
   if (tex_storage_error_check(ctx, texObj, dims, target, levels,
382
                               internalformat, width, height, depth, dsa)) {
383
      return; /* error was recorded */
384
   }
385
 
386
 
387
   texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
388
                                           internalformat, GL_NONE, GL_NONE);
389
   assert(texFormat != MESA_FORMAT_NONE);
390
 
391
   /* check that width, height, depth are legal for the mipmap level */
392
   dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
393
                                                  width, height, depth, 0);
394
 
395
   sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
396
                                          width, height, depth, 0);
397
 
398
   if (_mesa_is_proxy_texture(target)) {
399
      if (dimensionsOK && sizeOK) {
400
         initialize_texture_fields(ctx, texObj, levels, width, height, depth,
401
                                   internalformat, texFormat);
402
      }
403
      else {
404
         /* clear all image fields for [levels] */
405
         clear_texture_fields(ctx, texObj);
406
      }
407
   }
408
   else {
409
      if (!dimensionsOK) {
410
         _mesa_error(ctx, GL_INVALID_VALUE,
411
                     "glTex%sStorage%uD(invalid width, height or depth)",
412
                     suffix, dims);
413
         return;
414
      }
415
 
416
      if (!sizeOK) {
417
         _mesa_error(ctx, GL_OUT_OF_MEMORY,
418
                     "glTex%sStorage%uD(texture too large)",
419
                     suffix, dims);
420
      }
421
 
422
      assert(levels > 0);
423
      assert(width > 0);
424
      assert(height > 0);
425
      assert(depth > 0);
426
 
427
      if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth,
428
                                     internalformat, texFormat)) {
429
         return;
430
      }
431
 
432
      /* Do actual texture memory allocation */
433
      if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels,
434
                                           width, height, depth)) {
435
         /* Reset the texture images' info to zeros.
436
          * Strictly speaking, we probably don't have to do this since
437
          * generating GL_OUT_OF_MEMORY can leave things in an undefined
438
          * state but this puts things in a consistent state.
439
          */
440
         clear_texture_fields(ctx, texObj);
441
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
442
                     suffix, dims);
443
         return;
444
      }
445
 
446
      _mesa_set_texture_view_state(ctx, texObj, target, levels);
447
 
448
   }
449
}
450
 
451
/**
452
 * Helper used by _mesa_TexStorage1/2/3D().
453
 */
454
static void
455
texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat,
456
           GLsizei width, GLsizei height, GLsizei depth)
457
{
458
   struct gl_texture_object *texObj;
459
   GET_CURRENT_CONTEXT(ctx);
460
 
461
   /* target check */
462
   /* This is done here so that _mesa_texture_storage can receive unsized
463
    * formats. */
464
   if (!legal_texobj_target(ctx, dims, target)) {
465
      _mesa_error(ctx, GL_INVALID_ENUM,
466
                  "glTexStorage%uD(illegal target=%s)",
467
                  dims, _mesa_lookup_enum_by_nr(target));
468
      return;
469
   }
470
 
471
   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
472
      _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n",
473
                  dims,
474
                  _mesa_lookup_enum_by_nr(target), levels,
475
                  _mesa_lookup_enum_by_nr(internalformat),
476
                  width, height, depth);
477
   /* Check the format to make sure it is sized. */
478
   if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
479
      _mesa_error(ctx, GL_INVALID_ENUM,
480
                  "glTexStorage%uD(internalformat = %s)", dims,
481
                  _mesa_lookup_enum_by_nr(internalformat));
482
      return;
483
   }
484
 
485
   texObj = _mesa_get_current_tex_object(ctx, target);
486
   if (!texObj)
487
      return;
488
 
489
   _mesa_texture_storage(ctx, dims, texObj, target, levels,
490
                         internalformat, width, height, depth, false);
491
}
492
 
493
/**
494
 * Helper used by _mesa_TextureStorage1/2/3D().
495
 */
496
static void
497
texturestorage(GLuint dims, GLuint texture, GLsizei levels,
498
               GLenum internalformat, GLsizei width, GLsizei height,
499
               GLsizei depth)
500
{
501
   struct gl_texture_object *texObj;
502
   GET_CURRENT_CONTEXT(ctx);
503
 
504
   if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
505
      _mesa_debug(ctx, "glTextureStorage%uD %d %d %s %d %d %d\n",
506
                  dims, texture, levels,
507
                  _mesa_lookup_enum_by_nr(internalformat),
508
                  width, height, depth);
509
 
510
   if (!ctx->Extensions.ARB_direct_state_access) {
511
      _mesa_error(ctx, GL_INVALID_OPERATION,
512
                  "glTextureStorage%uD(GL_ARB_direct_state_access "
513
                  "is not supported)", dims);
514
      return;
515
   }
516
 
517
   /* Check the format to make sure it is sized. */
518
   if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
519
      _mesa_error(ctx, GL_INVALID_ENUM,
520
                  "glTextureStorage%uD(internalformat = %s)", dims,
521
                  _mesa_lookup_enum_by_nr(internalformat));
522
      return;
523
   }
524
 
525
   /* Get the texture object by Name. */
526
   texObj = _mesa_lookup_texture(ctx, texture);
527
   if (!texObj) {
528
      _mesa_error(ctx, GL_INVALID_OPERATION,
529
                  "glTextureStorage%uD(texture = %d)", dims, texture);
530
      return;
531
   }
532
 
533
   /* target check */
534
   /* This is done here so that _mesa_texture_storage can receive unsized
535
    * formats. */
536
   if (!legal_texobj_target(ctx, dims, texObj->Target)) {
537
      _mesa_error(ctx, GL_INVALID_ENUM,
538
                  "glTextureStorage%uD(illegal target=%s)",
539
                  dims, _mesa_lookup_enum_by_nr(texObj->Target));
540
      return;
541
   }
542
 
543
   _mesa_texture_storage(ctx, dims, texObj, texObj->Target,
544
                         levels, internalformat, width, height, depth, true);
545
}
546
 
547
void GLAPIENTRY
548
_mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,
549
                   GLsizei width)
550
{
551
   texstorage(1, target, levels, internalformat, width, 1, 1);
552
}
553
 
554
 
555
void GLAPIENTRY
556
_mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat,
557
                   GLsizei width, GLsizei height)
558
{
559
   texstorage(2, target, levels, internalformat, width, height, 1);
560
}
561
 
562
 
563
void GLAPIENTRY
564
_mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
565
                   GLsizei width, GLsizei height, GLsizei depth)
566
{
567
   texstorage(3, target, levels, internalformat, width, height, depth);
568
}
569
 
570
void GLAPIENTRY
571
_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,
572
                       GLsizei width)
573
{
574
   texturestorage(1, texture, levels, internalformat, width, 1, 1);
575
}
576
 
577
 
578
void GLAPIENTRY
579
_mesa_TextureStorage2D(GLuint texture, GLsizei levels,
580
                       GLenum internalformat,
581
                       GLsizei width, GLsizei height)
582
{
583
   texturestorage(2, texture, levels, internalformat, width, height, 1);
584
}
585
 
586
void GLAPIENTRY
587
_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,
588
                       GLsizei width, GLsizei height, GLsizei depth)
589
{
590
   texturestorage(3, texture, levels, internalformat, width, height, depth);
591
}
592
 
593
 
594
/*
595
 * Note: we don't support GL_EXT_direct_state_access and the spec says
596
 * we don't need the following functions.  However, glew checks for the
597
 * presence of all six functions and will say that GL_ARB_texture_storage
598
 * is not supported if these functions are missing.
599
 */
600
 
601
 
602
void GLAPIENTRY
603
_mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels,
604
                          GLenum internalformat,
605
                          GLsizei width)
606
{
607
   GET_CURRENT_CONTEXT(ctx);
608
 
609
   (void) texture;
610
   (void) target;
611
   (void) levels;
612
   (void) internalformat;
613
   (void) width;
614
 
615
   _mesa_error(ctx, GL_INVALID_OPERATION,
616
               "glTextureStorage1DEXT not supported");
617
}
618
 
619
 
620
void GLAPIENTRY
621
_mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels,
622
                          GLenum internalformat,
623
                          GLsizei width, GLsizei height)
624
{
625
   GET_CURRENT_CONTEXT(ctx);
626
 
627
   (void) texture;
628
   (void) target;
629
   (void) levels;
630
   (void) internalformat;
631
   (void) width;
632
   (void) height;
633
 
634
   _mesa_error(ctx, GL_INVALID_OPERATION,
635
               "glTextureStorage2DEXT not supported");
636
}
637
 
638
 
639
 
640
void GLAPIENTRY
641
_mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
642
                          GLenum internalformat,
643
                          GLsizei width, GLsizei height, GLsizei depth)
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
   (void) depth;
654
 
655
   _mesa_error(ctx, GL_INVALID_OPERATION,
656
               "glTextureStorage3DEXT not supported");
657
}