2
* Mesa 3-D graphics library
4
* Copyright (C) 2011 VMware, Inc. All Rights Reserved.
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:
13
* The above copyright notice and this permission notice shall be included
14
* in all copies or substantial portions of the Software.
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.
27
* GL_ARB_texture_storage functions
38
#include "texstorage.h"
39
#include "textureview.h"
41
#include "glformats.h"
43
#include "api_exec_decl.h"
45
#include "state_tracker/st_cb_texture.h"
48
* Check if the given texture target is a legal texture object target
49
* for a glTexStorage() command.
50
* This is a bit different than legal_teximage_target() when it comes
54
_mesa_is_legal_tex_storage_target(const struct gl_context *ctx,
55
GLuint dims, GLenum target)
57
if (dims < 1 || dims > 3) {
58
_mesa_problem(ctx, "invalid dims=%u in _mesa_is_legal_tex_storage_target()", dims);
66
case GL_TEXTURE_CUBE_MAP:
74
case GL_TEXTURE_2D_ARRAY:
75
return ctx->Extensions.EXT_texture_array;
76
case GL_TEXTURE_CUBE_MAP_ARRAY:
77
return _mesa_has_texture_cube_map_array(ctx);
82
if (!_mesa_is_desktop_gl(ctx))
89
case GL_PROXY_TEXTURE_1D:
96
case GL_PROXY_TEXTURE_2D:
97
case GL_PROXY_TEXTURE_CUBE_MAP:
99
case GL_TEXTURE_RECTANGLE:
100
case GL_PROXY_TEXTURE_RECTANGLE:
101
return ctx->Extensions.NV_texture_rectangle;
102
case GL_TEXTURE_1D_ARRAY:
103
case GL_PROXY_TEXTURE_1D_ARRAY:
104
return ctx->Extensions.EXT_texture_array;
110
case GL_PROXY_TEXTURE_3D:
112
case GL_PROXY_TEXTURE_2D_ARRAY:
113
return ctx->Extensions.EXT_texture_array;
114
case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
115
return ctx->Extensions.ARB_texture_cube_map_array;
120
unreachable("impossible dimensions");
125
/** Helper to get a particular texture image in a texture object */
126
static struct gl_texture_image *
127
get_tex_image(struct gl_context *ctx,
128
struct gl_texture_object *texObj,
129
GLuint face, GLuint level)
131
const GLenum faceTarget =
132
(texObj->Target == GL_TEXTURE_CUBE_MAP ||
133
texObj->Target == GL_PROXY_TEXTURE_CUBE_MAP)
134
? GL_TEXTURE_CUBE_MAP_POSITIVE_X + face : texObj->Target;
135
return _mesa_get_tex_image(ctx, texObj, faceTarget, level);
141
initialize_texture_fields(struct gl_context *ctx,
142
struct gl_texture_object *texObj,
144
GLsizei width, GLsizei height, GLsizei depth,
145
GLenum internalFormat, mesa_format texFormat)
147
const GLenum target = texObj->Target;
148
const GLuint numFaces = _mesa_num_tex_faces(target);
149
GLint level, levelWidth = width, levelHeight = height, levelDepth = depth;
152
/* Set up all the texture object's gl_texture_images */
153
for (level = 0; level < levels; level++) {
154
for (face = 0; face < numFaces; face++) {
155
struct gl_texture_image *texImage =
156
get_tex_image(ctx, texObj, face, level);
159
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
163
_mesa_init_teximage_fields(ctx, texImage,
164
levelWidth, levelHeight, levelDepth,
165
0, internalFormat, texFormat);
168
_mesa_next_mipmap_level_size(target, 0,
169
levelWidth, levelHeight, levelDepth,
170
&levelWidth, &levelHeight, &levelDepth);
177
* Clear all fields of texture object to zeros. Used for proxy texture tests
178
* and to clean up when a texture memory allocation fails.
181
clear_texture_fields(struct gl_context *ctx,
182
struct gl_texture_object *texObj)
184
const GLenum target = texObj->Target;
185
const GLuint numFaces = _mesa_num_tex_faces(target);
189
for (level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) {
190
for (face = 0; face < numFaces; face++) {
191
struct gl_texture_image *texImage =
192
get_tex_image(ctx, texObj, face, level);
195
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
199
_mesa_clear_texture_image(ctx, texImage);
206
* Update/re-validate framebuffer object.
209
update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
211
const unsigned numFaces = _mesa_num_tex_faces(texObj->Target);
212
for (int level = 0; level < ARRAY_SIZE(texObj->Image[0]); level++) {
213
for (unsigned face = 0; face < numFaces; face++)
214
_mesa_update_fbo_texture(ctx, texObj, face, level);
220
_mesa_is_legal_tex_storage_format(const struct gl_context *ctx,
221
GLenum internalformat)
223
/* check internal format - note that only sized formats are allowed */
224
switch (internalformat) {
227
case GL_LUMINANCE_ALPHA:
234
case GL_DEPTH_COMPONENT:
235
case GL_DEPTH_STENCIL:
236
case GL_COMPRESSED_ALPHA:
237
case GL_COMPRESSED_LUMINANCE_ALPHA:
238
case GL_COMPRESSED_LUMINANCE:
239
case GL_COMPRESSED_INTENSITY:
240
case GL_COMPRESSED_RGB:
241
case GL_COMPRESSED_RGBA:
242
case GL_COMPRESSED_SRGB:
243
case GL_COMPRESSED_SRGB_ALPHA:
244
case GL_COMPRESSED_SLUMINANCE:
245
case GL_COMPRESSED_SLUMINANCE_ALPHA:
247
case GL_GREEN_INTEGER:
248
case GL_BLUE_INTEGER:
249
case GL_ALPHA_INTEGER:
251
case GL_RGBA_INTEGER:
253
case GL_BGRA_INTEGER:
254
case GL_LUMINANCE_INTEGER_EXT:
255
case GL_LUMINANCE_ALPHA_INTEGER_EXT:
256
/* these unsized formats are illegal */
259
return _mesa_base_tex_format(ctx, internalformat) > 0;
265
* Do error checking for calls to glTexStorage1/2/3D().
266
* If an error is found, record it with _mesa_error(), unless the target
267
* is a proxy texture.
268
* \return GL_TRUE if any error, GL_FALSE otherwise.
271
tex_storage_error_check(struct gl_context *ctx,
272
struct gl_texture_object *texObj,
273
struct gl_memory_object *memObj,
274
GLuint dims, GLenum target,
275
GLsizei levels, GLenum internalformat,
276
GLsizei width, GLsizei height, GLsizei depth,
279
const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
280
(memObj ? "Mem" : "");
282
/* Legal format checking has been moved to texstorage and texturestorage in
283
* order to allow meta functions to use legacy formats. */
286
if (!_mesa_valid_tex_storage_dim(width, height, depth)) {
287
_mesa_error(ctx, GL_INVALID_VALUE,
288
"glTex%sStorage%uD(width, height or depth < 1)",
293
if (_mesa_is_compressed_format(ctx, internalformat)) {
295
if (!_mesa_target_can_be_compressed(ctx, target, internalformat, &err)) {
296
_mesa_error(ctx, err,
297
"glTex%sStorage%dD(internalformat = %s)", suffix, dims,
298
_mesa_enum_to_string(internalformat));
305
_mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)",
310
/* check levels against maximum (note different error than above) */
311
if (levels > (GLint) _mesa_max_texture_levels(ctx, target)) {
312
_mesa_error(ctx, GL_INVALID_OPERATION,
313
"glTex%sStorage%uD(levels too large)",
318
/* check levels against width/height/depth */
319
if (levels > _mesa_get_tex_max_num_levels(target, width, height, depth)) {
320
_mesa_error(ctx, GL_INVALID_OPERATION,
321
"glTex%sStorage%uD(too many levels"
322
" for max texture dimension)",
327
/* non-default texture object check */
328
if (!_mesa_is_proxy_texture(target) && (!texObj || (texObj->Name == 0))) {
329
_mesa_error(ctx, GL_INVALID_OPERATION,
330
"glTex%sStorage%uD(texture object 0)",
335
/* Check if texObj->Immutable is set */
336
if (!_mesa_is_proxy_texture(target) && texObj->Immutable) {
337
_mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(immutable)",
342
/* additional checks for depth textures */
343
if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) {
344
_mesa_error(ctx, GL_INVALID_OPERATION, "glTex%sStorage%uD(bad target for texture)",
353
_mesa_sparse_texture_error_check(struct gl_context *ctx, GLuint dims,
354
struct gl_texture_object *texObj,
355
mesa_format format, GLenum target, GLsizei levels,
356
GLsizei width, GLsizei height, GLsizei depth,
360
int index = texObj->VirtualPageSizeIndex;
361
if (!st_GetSparseTextureVirtualPageSize(ctx, target, format, index,
363
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(sparse index = %d)",
368
if (target == GL_TEXTURE_3D) {
369
if (width > ctx->Const.MaxSparse3DTextureSize ||
370
height > ctx->Const.MaxSparse3DTextureSize ||
371
depth > ctx->Const.MaxSparse3DTextureSize)
372
goto exceed_max_size;
374
if (width > ctx->Const.MaxSparseTextureSize ||
375
height > ctx->Const.MaxSparseTextureSize)
376
goto exceed_max_size;
378
if (target == GL_TEXTURE_2D_ARRAY ||
379
target == GL_TEXTURE_CUBE_MAP_ARRAY) {
380
if (depth > ctx->Const.MaxSparseArrayTextureLayers)
381
goto exceed_max_size;
382
} else if (target == GL_TEXTURE_1D_ARRAY) {
383
if (height > ctx->Const.MaxSparseArrayTextureLayers)
384
goto exceed_max_size;
388
/* ARB_sparse_texture2 allow non-page-aligned base texture size. */
389
if (!_mesa_has_ARB_sparse_texture2(ctx) &&
390
(width % px || height % py || depth % pz)) {
391
_mesa_error(ctx, GL_INVALID_VALUE, "%s(sparse page size)", func);
395
/* ARB_sparse_texture spec:
397
* If the value of SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB is FALSE,
398
* then TexStorage* will generate an INVALID_OPERATION error if
399
* * the texture's TEXTURE_SPARSE_ARB parameter is TRUE,
400
* * <target> is one of TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY,
401
* TEXTURE_CUBE_MAP, or TEXTURE_CUBE_MAP_ARRAY, and
402
* * for the virtual page size corresponding to the
403
* VIRTUAL_PAGE_SIZE_INDEX_ARB parameter, either of the following is
405
* - <width> is not a multiple of VIRTUAL_PAGE_SIZE_X_ARB *
407
* - <height> is not a multiple of VIRTUAL_PAGE_SIZE_Y_ARB *
410
* This make sure all allocated mipmap level size is multiple of virtual
411
* page size when SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB is FALSE.
413
if (!ctx->Const.SparseTextureFullArrayCubeMipmaps &&
414
(target == GL_TEXTURE_1D_ARRAY ||
415
target == GL_TEXTURE_2D_ARRAY ||
416
target == GL_TEXTURE_CUBE_MAP ||
417
target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
418
(width % (px << (levels - 1)) ||
419
height % (py << (levels - 1)))) {
420
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(sparse array align)", func);
427
_mesa_error(ctx, GL_INVALID_VALUE, "%s(exceed max sparse size)", func);
432
* Helper that does the storage allocation for _mesa_TexStorage1/2/3D()
433
* and _mesa_TextureStorage1/2/3D().
435
static ALWAYS_INLINE void
436
texture_storage(struct gl_context *ctx, GLuint dims,
437
struct gl_texture_object *texObj,
438
struct gl_memory_object *memObj, GLenum target,
439
GLsizei levels, GLenum internalformat, GLsizei width,
440
GLsizei height, GLsizei depth, GLuint64 offset, bool dsa,
443
GLboolean sizeOK = GL_TRUE, dimensionsOK = GL_TRUE;
444
mesa_format texFormat;
445
const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
446
(memObj ? "Mem" : "");
451
if (tex_storage_error_check(ctx, texObj, memObj, dims, target, levels,
452
internalformat, width, height, depth, dsa)) {
453
return; /* error was recorded */
457
texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
458
internalformat, GL_NONE, GL_NONE);
461
/* check that width, height, depth are legal for the mipmap level */
462
dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
463
width, height, depth, 0);
465
sizeOK = st_TestProxyTexImage(ctx, target, levels, 0, texFormat,
466
1, width, height, depth);
469
if (_mesa_is_proxy_texture(target)) {
470
if (dimensionsOK && sizeOK) {
471
initialize_texture_fields(ctx, texObj, levels, width, height, depth,
472
internalformat, texFormat);
475
/* clear all image fields for [levels] */
476
clear_texture_fields(ctx, texObj);
482
_mesa_error(ctx, GL_INVALID_VALUE,
483
"glTex%sStorage%uD(invalid width, height or depth)",
489
_mesa_error(ctx, GL_OUT_OF_MEMORY,
490
"glTex%sStorage%uD(texture too large)",
495
if (texObj->IsSparse) {
497
snprintf(func, 32, "glTex%sStorage%uD", suffix, dims);
498
if (_mesa_sparse_texture_error_check(ctx, dims, texObj, texFormat, target,
499
levels, width, height, depth, func))
500
return; /* error was recorded */
509
if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth,
510
internalformat, texFormat)) {
514
/* Setup the backing memory */
516
if (!st_SetTextureStorageForMemoryObject(ctx, texObj, memObj,
518
width, height, depth,
521
clear_texture_fields(ctx, texObj);
526
if (!st_AllocTextureStorage(ctx, texObj, levels,
527
width, height, depth)) {
528
/* Reset the texture images' info to zeros.
529
* Strictly speaking, we probably don't have to do this since
530
* generating GL_OUT_OF_MEMORY can leave things in an undefined
531
* state but this puts things in a consistent state.
533
clear_texture_fields(ctx, texObj);
534
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
540
_mesa_set_texture_view_state(ctx, texObj, target, levels);
542
update_fbo_texture(ctx, texObj);
548
texture_storage_error(struct gl_context *ctx, GLuint dims,
549
struct gl_texture_object *texObj,
550
GLenum target, GLsizei levels,
551
GLenum internalformat, GLsizei width,
552
GLsizei height, GLsizei depth, bool dsa)
554
texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat,
555
width, height, depth, dsa, 0, false);
560
texture_storage_no_error(struct gl_context *ctx, GLuint dims,
561
struct gl_texture_object *texObj,
562
GLenum target, GLsizei levels,
563
GLenum internalformat, GLsizei width,
564
GLsizei height, GLsizei depth, bool dsa)
566
texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat,
567
width, height, depth, dsa, 0, true);
572
* Helper used by _mesa_TexStorage1/2/3D().
575
texstorage_error(GLuint dims, GLenum target, GLsizei levels,
576
GLenum internalformat, GLsizei width, GLsizei height,
577
GLsizei depth, const char *caller)
579
struct gl_texture_object *texObj;
580
GET_CURRENT_CONTEXT(ctx);
582
/* Check target. This is done here so that texture_storage
583
* can receive unsized formats.
585
if (!_mesa_is_legal_tex_storage_target(ctx, dims, target)) {
586
_mesa_error(ctx, GL_INVALID_ENUM,
587
"%s(illegal target=%s)",
588
caller, _mesa_enum_to_string(target));
592
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
593
_mesa_debug(ctx, "%s %s %d %s %d %d %d\n", caller,
594
_mesa_enum_to_string(target), levels,
595
_mesa_enum_to_string(internalformat),
596
width, height, depth);
598
/* Check the format to make sure it is sized. */
599
if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
600
_mesa_error(ctx, GL_INVALID_ENUM,
601
"%s(internalformat = %s)", caller,
602
_mesa_enum_to_string(internalformat));
606
texObj = _mesa_get_current_tex_object(ctx, target);
610
texture_storage_error(ctx, dims, texObj, target, levels,
611
internalformat, width, height, depth, false);
616
texstorage_no_error(GLuint dims, GLenum target, GLsizei levels,
617
GLenum internalformat, GLsizei width, GLsizei height,
620
GET_CURRENT_CONTEXT(ctx);
622
struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target);
623
texture_storage_no_error(ctx, dims, texObj, target, levels,
624
internalformat, width, height, depth, false);
629
* Helper used by _mesa_TextureStorage1/2/3D().
632
texturestorage_error(GLuint dims, GLuint texture, GLsizei levels,
633
GLenum internalformat, GLsizei width, GLsizei height,
634
GLsizei depth, const char *caller)
636
struct gl_texture_object *texObj;
637
GET_CURRENT_CONTEXT(ctx);
639
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
640
_mesa_debug(ctx, "%s %d %d %s %d %d %d\n",
641
caller, texture, levels,
642
_mesa_enum_to_string(internalformat),
643
width, height, depth);
645
/* Check the format to make sure it is sized. */
646
if (!_mesa_is_legal_tex_storage_format(ctx, internalformat)) {
647
_mesa_error(ctx, GL_INVALID_ENUM,
648
"%s(internalformat = %s)", caller,
649
_mesa_enum_to_string(internalformat));
653
texObj = _mesa_lookup_texture_err(ctx, texture, caller);
657
/* Check target. This is done here so that texture_storage
658
* can receive unsized formats.
660
if (!_mesa_is_legal_tex_storage_target(ctx, dims, texObj->Target)) {
661
_mesa_error(ctx, GL_INVALID_OPERATION,
662
"%s(illegal target=%s)", caller,
663
_mesa_enum_to_string(texObj->Target));
667
texture_storage_error(ctx, dims, texObj, texObj->Target,
668
levels, internalformat, width, height, depth, true);
673
texturestorage_no_error(GLuint dims, GLuint texture, GLsizei levels,
674
GLenum internalformat, GLsizei width, GLsizei height,
677
GET_CURRENT_CONTEXT(ctx);
679
struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture);
680
texture_storage_no_error(ctx, dims, texObj, texObj->Target,
681
levels, internalformat, width, height, depth, true);
686
_mesa_TexStorage1D_no_error(GLenum target, GLsizei levels,
687
GLenum internalformat, GLsizei width)
689
texstorage_no_error(1, target, levels, internalformat, width, 1, 1);
694
_mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,
697
texstorage_error(1, target, levels, internalformat, width, 1, 1,
703
_mesa_TexStorage2D_no_error(GLenum target, GLsizei levels,
704
GLenum internalformat, GLsizei width,
707
texstorage_no_error(2, target, levels, internalformat, width, height, 1);
712
_mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat,
713
GLsizei width, GLsizei height)
715
texstorage_error(2, target, levels, internalformat, width, height, 1,
721
_mesa_TexStorage3D_no_error(GLenum target, GLsizei levels,
722
GLenum internalformat, GLsizei width,
723
GLsizei height, GLsizei depth)
725
texstorage_no_error(3, target, levels, internalformat, width, height, depth);
730
_mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
731
GLsizei width, GLsizei height, GLsizei depth)
733
texstorage_error(3, target, levels, internalformat, width, height, depth,
739
_mesa_TextureStorage1D_no_error(GLuint texture, GLsizei levels,
740
GLenum internalformat, GLsizei width)
742
texturestorage_no_error(1, texture, levels, internalformat, width, 1, 1);
747
_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,
750
texturestorage_error(1, texture, levels, internalformat, width, 1, 1,
751
"glTextureStorage1D");
756
_mesa_TextureStorage2D_no_error(GLuint texture, GLsizei levels,
757
GLenum internalformat,
758
GLsizei width, GLsizei height)
760
texturestorage_no_error(2, texture, levels, internalformat, width, height, 1);
765
_mesa_TextureStorage2D(GLuint texture, GLsizei levels,
766
GLenum internalformat,
767
GLsizei width, GLsizei height)
769
texturestorage_error(2, texture, levels, internalformat, width, height, 1,
770
"glTextureStorage2D");
775
_mesa_TextureStorage3D_no_error(GLuint texture, GLsizei levels,
776
GLenum internalformat, GLsizei width,
777
GLsizei height, GLsizei depth)
779
texturestorage_no_error(3, texture, levels, internalformat, width, height,
785
_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,
786
GLsizei width, GLsizei height, GLsizei depth)
788
texturestorage_error(3, texture, levels, internalformat, width, height, depth,
789
"glTextureStorage3D");
794
_mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels,
795
GLenum internalformat,
798
GET_CURRENT_CONTEXT(ctx);
799
/* 'texture' must always be initialized, even if the call to
800
* glTextureStorage1DEXT will generate an error.
802
if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
803
"glTextureStorage1DEXT"))
805
texturestorage_error(1, texture, levels, internalformat, width, 1, 1,
806
"glTextureStorage1DEXT");
811
_mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels,
812
GLenum internalformat,
813
GLsizei width, GLsizei height)
815
GET_CURRENT_CONTEXT(ctx);
816
/* 'texture' must always be initialized, even if the call to
817
* glTextureStorage2DEXT will generate an error.
819
if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
820
"glTextureStorage2DEXT"))
822
texturestorage_error(2, texture, levels, internalformat, width, height, 1,
823
"glTextureStorage2DEXT");
828
_mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
829
GLenum internalformat,
830
GLsizei width, GLsizei height, GLsizei depth)
832
GET_CURRENT_CONTEXT(ctx);
833
/* 'texture' must always be initialized, even if the call to
834
* glTextureStorage3DEXT will generate an error.
836
if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
837
"glTextureStorage3DEXT"))
839
texturestorage_error(3, texture, levels, internalformat, width, height, depth,
840
"glTextureStorage3DEXT");
845
_mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims,
846
struct gl_texture_object *texObj,
847
struct gl_memory_object *memObj,
848
GLenum target, GLsizei levels,
849
GLenum internalformat, GLsizei width,
850
GLsizei height, GLsizei depth,
851
GLuint64 offset, bool dsa)
855
texture_storage(ctx, dims, texObj, memObj, target, levels, internalformat,
856
width, height, depth, offset, dsa, false);