~mmach/netext73/mesa_2004

« back to all changes in this revision

Viewing changes to src/mesa/main/texstorage.c

  • Committer: mmach
  • Date: 2022-09-22 20:00:35 UTC
  • Revision ID: netbit73@gmail.com-20220922200035-j2mt0pv92d002zy3
2022-09-22 21:17:58

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Mesa 3-D graphics library
 
3
 *
 
4
 * Copyright (C) 2011  VMware, Inc.  All Rights Reserved.
 
5
 *
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a
 
7
 * copy of this software and associated documentation files (the "Software"),
 
8
 * to deal in the Software without restriction, including without limitation
 
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
10
 * and/or sell copies of the Software, and to permit persons to whom the
 
11
 * Software is furnished to do so, subject to the following conditions:
 
12
 *
 
13
 * The above copyright notice and this permission notice shall be included
 
14
 * in all copies or substantial portions of the Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
22
 * OTHER DEALINGS IN THE SOFTWARE.
 
23
 */
 
24
 
 
25
/**
 
26
 * \file texstorage.c
 
27
 * GL_ARB_texture_storage functions
 
28
 */
 
29
 
 
30
#include "glheader.h"
 
31
#include "context.h"
 
32
#include "enums.h"
 
33
 
 
34
#include "macros.h"
 
35
#include "teximage.h"
 
36
#include "texobj.h"
 
37
#include "mipmap.h"
 
38
#include "texstorage.h"
 
39
#include "textureview.h"
 
40
#include "mtypes.h"
 
41
#include "glformats.h"
 
42
#include "hash.h"
 
43
#include "api_exec_decl.h"
 
44
 
 
45
#include "state_tracker/st_cb_texture.h"
 
46
 
 
47
/**
 
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
 
51
 * to cube maps.
 
52
 */
 
53
bool
 
54
_mesa_is_legal_tex_storage_target(const struct gl_context *ctx,
 
55
                                  GLuint dims, GLenum target)
 
56
{
 
57
   if (dims < 1 || dims > 3) {
 
58
      _mesa_problem(ctx, "invalid dims=%u in _mesa_is_legal_tex_storage_target()", dims);
 
59
      return false;
 
60
   }
 
61
 
 
62
   switch (dims) {
 
63
   case 2:
 
64
      switch (target) {
 
65
      case GL_TEXTURE_2D:
 
66
      case GL_TEXTURE_CUBE_MAP:
 
67
         return true;
 
68
      }
 
69
      break;
 
70
   case 3:
 
71
      switch (target) {
 
72
      case GL_TEXTURE_3D:
 
73
         return true;
 
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);
 
78
      }
 
79
      break;
 
80
   }
 
81
 
 
82
   if (!_mesa_is_desktop_gl(ctx))
 
83
      return false;
 
84
 
 
85
   switch (dims) {
 
86
   case 1:
 
87
      switch (target) {
 
88
      case GL_TEXTURE_1D:
 
89
      case GL_PROXY_TEXTURE_1D:
 
90
         return true;
 
91
      default:
 
92
         return false;
 
93
      }
 
94
   case 2:
 
95
      switch (target) {
 
96
      case GL_PROXY_TEXTURE_2D:
 
97
      case GL_PROXY_TEXTURE_CUBE_MAP:
 
98
         return true;
 
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;
 
105
      default:
 
106
         return false;
 
107
      }
 
108
   case 3:
 
109
      switch (target) {
 
110
      case GL_PROXY_TEXTURE_3D:
 
111
         return true;
 
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;
 
116
      default:
 
117
         return false;
 
118
      }
 
119
   default:
 
120
      unreachable("impossible dimensions");
 
121
   }
 
122
}
 
123
 
 
124
 
 
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)
 
130
{
 
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);
 
136
}
 
137
 
 
138
 
 
139
 
 
140
static GLboolean
 
141
initialize_texture_fields(struct gl_context *ctx,
 
142
                          struct gl_texture_object *texObj,
 
143
                          GLint levels,
 
144
                          GLsizei width, GLsizei height, GLsizei depth,
 
145
                          GLenum internalFormat, mesa_format texFormat)
 
146
{
 
147
   const GLenum target = texObj->Target;
 
148
   const GLuint numFaces = _mesa_num_tex_faces(target);
 
149
   GLint level, levelWidth = width, levelHeight = height, levelDepth = depth;
 
150
   GLuint face;
 
151
 
 
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);
 
157
 
 
158
         if (!texImage) {
 
159
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
 
160
            return GL_FALSE;
 
161
         }
 
162
 
 
163
         _mesa_init_teximage_fields(ctx, texImage,
 
164
                                    levelWidth, levelHeight, levelDepth,
 
165
                                    0, internalFormat, texFormat);
 
166
      }
 
167
 
 
168
      _mesa_next_mipmap_level_size(target, 0,
 
169
                                   levelWidth, levelHeight, levelDepth,
 
170
                                   &levelWidth, &levelHeight, &levelDepth);
 
171
   }
 
172
   return GL_TRUE;
 
173
}
 
174
 
 
175
 
 
176
/**
 
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.
 
179
 */
 
180
static void
 
181
clear_texture_fields(struct gl_context *ctx,
 
182
                     struct gl_texture_object *texObj)
 
183
{
 
184
   const GLenum target = texObj->Target;
 
185
   const GLuint numFaces = _mesa_num_tex_faces(target);
 
186
   GLint level;
 
187
   GLuint face;
 
188
 
 
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);
 
193
 
 
194
         if (!texImage) {
 
195
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
 
196
            return;
 
197
         }
 
198
 
 
199
         _mesa_clear_texture_image(ctx, texImage);
 
200
      }
 
201
   }
 
202
}
 
203
 
 
204
 
 
205
/**
 
206
 * Update/re-validate framebuffer object.
 
207
 */
 
208
static void
 
209
update_fbo_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
 
210
{
 
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);
 
215
   }
 
216
}
 
217
 
 
218
 
 
219
GLboolean
 
220
_mesa_is_legal_tex_storage_format(const struct gl_context *ctx,
 
221
                                  GLenum internalformat)
 
222
{
 
223
   /* check internal format - note that only sized formats are allowed */
 
224
   switch (internalformat) {
 
225
   case GL_ALPHA:
 
226
   case GL_LUMINANCE:
 
227
   case GL_LUMINANCE_ALPHA:
 
228
   case GL_INTENSITY:
 
229
   case GL_RED:
 
230
   case GL_RG:
 
231
   case GL_RGB:
 
232
   case GL_RGBA:
 
233
   case GL_BGRA:
 
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:
 
246
   case GL_RED_INTEGER:
 
247
   case GL_GREEN_INTEGER:
 
248
   case GL_BLUE_INTEGER:
 
249
   case GL_ALPHA_INTEGER:
 
250
   case GL_RGB_INTEGER:
 
251
   case GL_RGBA_INTEGER:
 
252
   case GL_BGR_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 */
 
257
      return GL_FALSE;
 
258
   default:
 
259
      return _mesa_base_tex_format(ctx, internalformat) > 0;
 
260
   }
 
261
}
 
262
 
 
263
 
 
264
/**
 
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.
 
269
 */
 
270
static GLboolean
 
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,
 
277
                        bool dsa)
 
278
{
 
279
   const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
 
280
                              (memObj ? "Mem" : "");
 
281
 
 
282
   /* Legal format checking has been moved to texstorage and texturestorage in
 
283
    * order to allow meta functions to use legacy formats. */
 
284
 
 
285
   /* size check */
 
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)",
 
289
                  suffix, dims);
 
290
      return GL_TRUE;
 
291
   }
 
292
 
 
293
   if (_mesa_is_compressed_format(ctx, internalformat)) {
 
294
      GLenum err;
 
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));
 
299
         return GL_TRUE;
 
300
      }
 
301
   }
 
302
 
 
303
   /* levels check */
 
304
   if (levels < 1) {
 
305
      _mesa_error(ctx, GL_INVALID_VALUE, "glTex%sStorage%uD(levels < 1)",
 
306
                  suffix, dims);
 
307
      return GL_TRUE;
 
308
   }
 
309
 
 
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)",
 
314
                  suffix, dims);
 
315
      return GL_TRUE;
 
316
   }
 
317
 
 
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)",
 
323
                  suffix, dims);
 
324
      return GL_TRUE;
 
325
   }
 
326
 
 
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)",
 
331
                  suffix, dims);
 
332
      return GL_TRUE;
 
333
   }
 
334
 
 
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)",
 
338
                  suffix, dims);
 
339
      return GL_TRUE;
 
340
   }
 
341
 
 
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)",
 
345
                  suffix, dims);
 
346
      return GL_TRUE;
 
347
   }
 
348
 
 
349
   return GL_FALSE;
 
350
}
 
351
 
 
352
GLboolean
 
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,
 
357
                                 const char *func)
 
358
{
 
359
   int px, py, pz;
 
360
   int index = texObj->VirtualPageSizeIndex;
 
361
   if (!st_GetSparseTextureVirtualPageSize(ctx, target, format, index,
 
362
                                           &px, &py, &pz)) {
 
363
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(sparse index = %d)",
 
364
                  func, index);
 
365
      return GL_TRUE;
 
366
   }
 
367
 
 
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;
 
373
   } else {
 
374
      if (width > ctx->Const.MaxSparseTextureSize ||
 
375
          height > ctx->Const.MaxSparseTextureSize)
 
376
         goto exceed_max_size;
 
377
 
 
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;
 
385
      }
 
386
   }
 
387
 
 
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);
 
392
      return GL_TRUE;
 
393
   }
 
394
 
 
395
   /* ARB_sparse_texture spec:
 
396
    *
 
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
 
404
    *       true:
 
405
    *         - <width> is not a multiple of VIRTUAL_PAGE_SIZE_X_ARB *
 
406
    *            2^(<levels>-1), or
 
407
    *         - <height> is not a multiple of VIRTUAL_PAGE_SIZE_Y_ARB *
 
408
    *            2^(<levels>-1).
 
409
    *
 
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.
 
412
    */
 
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);
 
421
      return GL_TRUE;
 
422
   }
 
423
 
 
424
   return GL_FALSE;
 
425
 
 
426
exceed_max_size:
 
427
   _mesa_error(ctx, GL_INVALID_VALUE, "%s(exceed max sparse size)", func);
 
428
   return GL_TRUE;
 
429
}
 
430
 
 
431
/**
 
432
 * Helper that does the storage allocation for _mesa_TexStorage1/2/3D()
 
433
 * and _mesa_TextureStorage1/2/3D().
 
434
 */
 
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,
 
441
                bool no_error)
 
442
{
 
443
   GLboolean sizeOK = GL_TRUE, dimensionsOK = GL_TRUE;
 
444
   mesa_format texFormat;
 
445
   const char* suffix = dsa ? (memObj ? "tureMem" : "ture") :
 
446
                              (memObj ? "Mem" : "");
 
447
 
 
448
   assert(texObj);
 
449
 
 
450
   if (!no_error) {
 
451
      if (tex_storage_error_check(ctx, texObj, memObj, dims, target, levels,
 
452
                                  internalformat, width, height, depth, dsa)) {
 
453
         return; /* error was recorded */
 
454
      }
 
455
   }
 
456
 
 
457
   texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
 
458
                                           internalformat, GL_NONE, GL_NONE);
 
459
 
 
460
   if (!no_error) {
 
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);
 
464
 
 
465
      sizeOK = st_TestProxyTexImage(ctx, target, levels, 0, texFormat,
 
466
                                    1, width, height, depth);
 
467
   }
 
468
 
 
469
   if (_mesa_is_proxy_texture(target)) {
 
470
      if (dimensionsOK && sizeOK) {
 
471
         initialize_texture_fields(ctx, texObj, levels, width, height, depth,
 
472
                                   internalformat, texFormat);
 
473
      }
 
474
      else {
 
475
         /* clear all image fields for [levels] */
 
476
         clear_texture_fields(ctx, texObj);
 
477
      }
 
478
   }
 
479
   else {
 
480
      if (!no_error) {
 
481
         if (!dimensionsOK) {
 
482
            _mesa_error(ctx, GL_INVALID_VALUE,
 
483
                        "glTex%sStorage%uD(invalid width, height or depth)",
 
484
                        suffix, dims);
 
485
            return;
 
486
         }
 
487
 
 
488
         if (!sizeOK) {
 
489
            _mesa_error(ctx, GL_OUT_OF_MEMORY,
 
490
                        "glTex%sStorage%uD(texture too large)",
 
491
                        suffix, dims);
 
492
            return;
 
493
         }
 
494
 
 
495
         if (texObj->IsSparse) {
 
496
            char func[32];
 
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 */
 
501
         }
 
502
      }
 
503
 
 
504
      assert(levels > 0);
 
505
      assert(width > 0);
 
506
      assert(height > 0);
 
507
      assert(depth > 0);
 
508
 
 
509
      if (!initialize_texture_fields(ctx, texObj, levels, width, height, depth,
 
510
                                     internalformat, texFormat)) {
 
511
         return;
 
512
      }
 
513
 
 
514
      /* Setup the backing memory */
 
515
      if (memObj) {
 
516
         if (!st_SetTextureStorageForMemoryObject(ctx, texObj, memObj,
 
517
                                                  levels,
 
518
                                                  width, height, depth,
 
519
                                                  offset)) {
 
520
 
 
521
            clear_texture_fields(ctx, texObj);
 
522
            return;
 
523
         }
 
524
      }
 
525
      else {
 
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.
 
532
             */
 
533
            clear_texture_fields(ctx, texObj);
 
534
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTex%sStorage%uD",
 
535
                        suffix, dims);
 
536
            return;
 
537
         }
 
538
      }
 
539
 
 
540
      _mesa_set_texture_view_state(ctx, texObj, target, levels);
 
541
 
 
542
      update_fbo_texture(ctx, texObj);
 
543
   }
 
544
}
 
545
 
 
546
 
 
547
static void
 
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)
 
553
{
 
554
   texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat,
 
555
                   width, height, depth, dsa, 0, false);
 
556
}
 
557
 
 
558
 
 
559
static void
 
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)
 
565
{
 
566
   texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat,
 
567
                   width, height, depth, dsa, 0, true);
 
568
}
 
569
 
 
570
 
 
571
/**
 
572
 * Helper used by _mesa_TexStorage1/2/3D().
 
573
 */
 
574
static void
 
575
texstorage_error(GLuint dims, GLenum target, GLsizei levels,
 
576
                 GLenum internalformat, GLsizei width, GLsizei height,
 
577
                 GLsizei depth, const char *caller)
 
578
{
 
579
   struct gl_texture_object *texObj;
 
580
   GET_CURRENT_CONTEXT(ctx);
 
581
 
 
582
   /* Check target.  This is done here so that texture_storage
 
583
    * can receive unsized formats.
 
584
    */
 
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));
 
589
      return;
 
590
   }
 
591
 
 
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);
 
597
 
 
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));
 
603
      return;
 
604
   }
 
605
 
 
606
   texObj = _mesa_get_current_tex_object(ctx, target);
 
607
   if (!texObj)
 
608
      return;
 
609
 
 
610
   texture_storage_error(ctx, dims, texObj, target, levels,
 
611
                         internalformat, width, height, depth, false);
 
612
}
 
613
 
 
614
 
 
615
static void
 
616
texstorage_no_error(GLuint dims, GLenum target, GLsizei levels,
 
617
                    GLenum internalformat, GLsizei width, GLsizei height,
 
618
                    GLsizei depth)
 
619
{
 
620
   GET_CURRENT_CONTEXT(ctx);
 
621
 
 
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);
 
625
}
 
626
 
 
627
 
 
628
/**
 
629
 * Helper used by _mesa_TextureStorage1/2/3D().
 
630
 */
 
631
static void
 
632
texturestorage_error(GLuint dims, GLuint texture, GLsizei levels,
 
633
                     GLenum internalformat, GLsizei width, GLsizei height,
 
634
                     GLsizei depth, const char *caller)
 
635
{
 
636
   struct gl_texture_object *texObj;
 
637
   GET_CURRENT_CONTEXT(ctx);
 
638
 
 
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);
 
644
 
 
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));
 
650
      return;
 
651
   }
 
652
 
 
653
   texObj = _mesa_lookup_texture_err(ctx, texture, caller);
 
654
   if (!texObj)
 
655
      return;
 
656
 
 
657
   /* Check target.  This is done here so that texture_storage
 
658
    * can receive unsized formats.
 
659
    */
 
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));
 
664
      return;
 
665
   }
 
666
 
 
667
   texture_storage_error(ctx, dims, texObj, texObj->Target,
 
668
                         levels, internalformat, width, height, depth, true);
 
669
}
 
670
 
 
671
 
 
672
static void
 
673
texturestorage_no_error(GLuint dims, GLuint texture, GLsizei levels,
 
674
                        GLenum internalformat, GLsizei width, GLsizei height,
 
675
                        GLsizei depth)
 
676
{
 
677
   GET_CURRENT_CONTEXT(ctx);
 
678
 
 
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);
 
682
}
 
683
 
 
684
 
 
685
void GLAPIENTRY
 
686
_mesa_TexStorage1D_no_error(GLenum target, GLsizei levels,
 
687
                            GLenum internalformat, GLsizei width)
 
688
{
 
689
   texstorage_no_error(1, target, levels, internalformat, width, 1, 1);
 
690
}
 
691
 
 
692
 
 
693
void GLAPIENTRY
 
694
_mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat,
 
695
                   GLsizei width)
 
696
{
 
697
   texstorage_error(1, target, levels, internalformat, width, 1, 1,
 
698
                    "glTexStorage1D");
 
699
}
 
700
 
 
701
 
 
702
void GLAPIENTRY
 
703
_mesa_TexStorage2D_no_error(GLenum target, GLsizei levels,
 
704
                            GLenum internalformat, GLsizei width,
 
705
                            GLsizei height)
 
706
{
 
707
   texstorage_no_error(2, target, levels, internalformat, width, height, 1);
 
708
}
 
709
 
 
710
 
 
711
void GLAPIENTRY
 
712
_mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat,
 
713
                   GLsizei width, GLsizei height)
 
714
{
 
715
   texstorage_error(2, target, levels, internalformat, width, height, 1,
 
716
                    "glTexStorage2D");
 
717
}
 
718
 
 
719
 
 
720
void GLAPIENTRY
 
721
_mesa_TexStorage3D_no_error(GLenum target, GLsizei levels,
 
722
                            GLenum internalformat, GLsizei width,
 
723
                            GLsizei height, GLsizei depth)
 
724
{
 
725
   texstorage_no_error(3, target, levels, internalformat, width, height, depth);
 
726
}
 
727
 
 
728
 
 
729
void GLAPIENTRY
 
730
_mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat,
 
731
                   GLsizei width, GLsizei height, GLsizei depth)
 
732
{
 
733
   texstorage_error(3, target, levels, internalformat, width, height, depth,
 
734
                    "glTexStorage3D");
 
735
}
 
736
 
 
737
 
 
738
void GLAPIENTRY
 
739
_mesa_TextureStorage1D_no_error(GLuint texture, GLsizei levels,
 
740
                                GLenum internalformat, GLsizei width)
 
741
{
 
742
   texturestorage_no_error(1, texture, levels, internalformat, width, 1, 1);
 
743
}
 
744
 
 
745
 
 
746
void GLAPIENTRY
 
747
_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat,
 
748
                       GLsizei width)
 
749
{
 
750
   texturestorage_error(1, texture, levels, internalformat, width, 1, 1,
 
751
                        "glTextureStorage1D");
 
752
}
 
753
 
 
754
 
 
755
void GLAPIENTRY
 
756
_mesa_TextureStorage2D_no_error(GLuint texture, GLsizei levels,
 
757
                                GLenum internalformat,
 
758
                                GLsizei width, GLsizei height)
 
759
{
 
760
   texturestorage_no_error(2, texture, levels, internalformat, width, height, 1);
 
761
}
 
762
 
 
763
 
 
764
void GLAPIENTRY
 
765
_mesa_TextureStorage2D(GLuint texture, GLsizei levels,
 
766
                       GLenum internalformat,
 
767
                       GLsizei width, GLsizei height)
 
768
{
 
769
   texturestorage_error(2, texture, levels, internalformat, width, height, 1,
 
770
                        "glTextureStorage2D");
 
771
}
 
772
 
 
773
 
 
774
void GLAPIENTRY
 
775
_mesa_TextureStorage3D_no_error(GLuint texture, GLsizei levels,
 
776
                                GLenum internalformat, GLsizei width,
 
777
                                GLsizei height, GLsizei depth)
 
778
{
 
779
   texturestorage_no_error(3, texture, levels, internalformat, width, height,
 
780
                           depth);
 
781
}
 
782
 
 
783
 
 
784
void GLAPIENTRY
 
785
_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat,
 
786
                       GLsizei width, GLsizei height, GLsizei depth)
 
787
{
 
788
   texturestorage_error(3, texture, levels, internalformat, width, height, depth,
 
789
                        "glTextureStorage3D");
 
790
}
 
791
 
 
792
 
 
793
void GLAPIENTRY
 
794
_mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels,
 
795
                          GLenum internalformat,
 
796
                          GLsizei width)
 
797
{
 
798
   GET_CURRENT_CONTEXT(ctx);
 
799
   /* 'texture' must always be initialized, even if the call to
 
800
    * glTextureStorage1DEXT will generate an error.
 
801
    */
 
802
   if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
 
803
                                       "glTextureStorage1DEXT"))
 
804
      return;
 
805
   texturestorage_error(1, texture, levels, internalformat, width, 1, 1,
 
806
                        "glTextureStorage1DEXT");
 
807
}
 
808
 
 
809
 
 
810
void GLAPIENTRY
 
811
_mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels,
 
812
                          GLenum internalformat,
 
813
                          GLsizei width, GLsizei height)
 
814
{
 
815
   GET_CURRENT_CONTEXT(ctx);
 
816
   /* 'texture' must always be initialized, even if the call to
 
817
    * glTextureStorage2DEXT will generate an error.
 
818
    */
 
819
   if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
 
820
                                       "glTextureStorage2DEXT"))
 
821
      return;
 
822
   texturestorage_error(2, texture, levels, internalformat, width, height, 1,
 
823
                        "glTextureStorage2DEXT");
 
824
}
 
825
 
 
826
 
 
827
void GLAPIENTRY
 
828
_mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels,
 
829
                          GLenum internalformat,
 
830
                          GLsizei width, GLsizei height, GLsizei depth)
 
831
{
 
832
   GET_CURRENT_CONTEXT(ctx);
 
833
   /* 'texture' must always be initialized, even if the call to
 
834
    * glTextureStorage3DEXT will generate an error.
 
835
    */
 
836
   if (!_mesa_lookup_or_create_texture(ctx, target, texture, false, true,
 
837
                                       "glTextureStorage3DEXT"))
 
838
      return;
 
839
   texturestorage_error(3, texture, levels, internalformat, width, height, depth,
 
840
                        "glTextureStorage3DEXT");
 
841
}
 
842
 
 
843
 
 
844
void
 
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)
 
852
{
 
853
   assert(memObj);
 
854
 
 
855
   texture_storage(ctx, dims, texObj, memObj, target, levels, internalformat,
 
856
                   width, height, depth, offset, dsa, false);
 
857
}