Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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) 2013 LunarG, Inc.
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 OR
17
 * 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 OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
 * DEALINGS IN THE SOFTWARE.
23
 *
24
 * Authors:
25
 *    Courtney Goeltzenleuchter 
26
 */
27
 
28
 
29
/**
30
 * \file textureview.c
31
 * GL_ARB_texture_view functions
32
 */
33
 
34
#include "glheader.h"
35
#include "context.h"
36
#include "enums.h"
37
#include "imports.h"
38
#include "macros.h"
39
#include "teximage.h"
40
#include "texobj.h"
41
#include "mipmap.h"
42
#include "texstorage.h"
43
#include "textureview.h"
44
#include "stdbool.h"
45
#include "mtypes.h"
46
 
47
/* Table 3.X.2 (Compatible internal formats for TextureView)
48
    ---------------------------------------------------------------------------
49
    | Class                 | Internal formats                                |
50
    ---------------------------------------------------------------------------
51
    | VIEW_CLASS_128_BITS   | RGBA32F, RGBA32UI, RGBA32I                      |
52
    ---------------------------------------------------------------------------
53
    | VIEW_CLASS_96_BITS    | RGB32F, RGB32UI, RGB32I                         |
54
    ---------------------------------------------------------------------------
55
    | VIEW_CLASS_64_BITS    | RGBA16F, RG32F, RGBA16UI, RG32UI, RGBA16I,      |
56
    |                       | RG32I, RGBA16, RGBA16_SNORM                     |
57
    ---------------------------------------------------------------------------
58
    | VIEW_CLASS_48_BITS    | RGB16, RGB16_SNORM, RGB16F, RGB16UI, RGB16I     |
59
    ---------------------------------------------------------------------------
60
    | VIEW_CLASS_32_BITS    | RG16F, R11F_G11F_B10F, R32F,                    |
61
    |                       | RGB10_A2UI, RGBA8UI, RG16UI, R32UI,             |
62
    |                       | RGBA8I, RG16I, R32I, RGB10_A2, RGBA8, RG16,     |
63
    |                       | RGBA8_SNORM, RG16_SNORM, SRGB8_ALPHA8, RGB9_E5  |
64
    ---------------------------------------------------------------------------
65
    | VIEW_CLASS_24_BITS    | RGB8, RGB8_SNORM, SRGB8, RGB8UI, RGB8I          |
66
    ---------------------------------------------------------------------------
67
    | VIEW_CLASS_16_BITS    | R16F, RG8UI, R16UI, RG8I, R16I, RG8, R16,       |
68
    |                       | RG8_SNORM, R16_SNORM                            |
69
    ---------------------------------------------------------------------------
70
    | VIEW_CLASS_8_BITS     | R8UI, R8I, R8, R8_SNORM                         |
71
    ---------------------------------------------------------------------------
72
    | VIEW_CLASS_RGTC1_RED  | COMPRESSED_RED_RGTC1,                           |
73
    |                       | COMPRESSED_SIGNED_RED_RGTC1                     |
74
    ---------------------------------------------------------------------------
75
    | VIEW_CLASS_RGTC2_RG   | COMPRESSED_RG_RGTC2,                            |
76
    |                       | COMPRESSED_SIGNED_RG_RGTC2                      |
77
    ---------------------------------------------------------------------------
78
    | VIEW_CLASS_BPTC_UNORM | COMPRESSED_RGBA_BPTC_UNORM,                     |
79
    |                       | COMPRESSED_SRGB_ALPHA_BPTC_UNORM                |
80
    ---------------------------------------------------------------------------
81
    | VIEW_CLASS_BPTC_FLOAT | COMPRESSED_RGB_BPTC_SIGNED_FLOAT,               |
82
    |                       | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT              |
83
    ---------------------------------------------------------------------------
84
 */
85
struct internal_format_class_info {
86
   GLenum view_class;
87
   GLenum internal_format;
88
};
89
static const struct internal_format_class_info compatible_internal_formats[] = {
90
   {GL_VIEW_CLASS_128_BITS, GL_RGBA32F},
91
   {GL_VIEW_CLASS_128_BITS, GL_RGBA32UI},
92
   {GL_VIEW_CLASS_128_BITS, GL_RGBA32I},
93
   {GL_VIEW_CLASS_96_BITS, GL_RGB32F},
94
   {GL_VIEW_CLASS_96_BITS, GL_RGB32UI},
95
   {GL_VIEW_CLASS_96_BITS, GL_RGB32I},
96
   {GL_VIEW_CLASS_64_BITS, GL_RGBA16F},
97
   {GL_VIEW_CLASS_64_BITS, GL_RG32F},
98
   {GL_VIEW_CLASS_64_BITS, GL_RGBA16UI},
99
   {GL_VIEW_CLASS_64_BITS, GL_RG32UI},
100
   {GL_VIEW_CLASS_64_BITS, GL_RGBA16I},
101
   {GL_VIEW_CLASS_64_BITS, GL_RG32I},
102
   {GL_VIEW_CLASS_64_BITS, GL_RGBA16},
103
   {GL_VIEW_CLASS_64_BITS, GL_RGBA16_SNORM},
104
   {GL_VIEW_CLASS_48_BITS, GL_RGB16},
105
   {GL_VIEW_CLASS_48_BITS, GL_RGB16_SNORM},
106
   {GL_VIEW_CLASS_48_BITS, GL_RGB16F},
107
   {GL_VIEW_CLASS_48_BITS, GL_RGB16UI},
108
   {GL_VIEW_CLASS_48_BITS, GL_RGB16I},
109
   {GL_VIEW_CLASS_32_BITS, GL_RG16F},
110
   {GL_VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F},
111
   {GL_VIEW_CLASS_32_BITS, GL_R32F},
112
   {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2UI},
113
   {GL_VIEW_CLASS_32_BITS, GL_RGBA8UI},
114
   {GL_VIEW_CLASS_32_BITS, GL_RG16UI},
115
   {GL_VIEW_CLASS_32_BITS, GL_R32UI},
116
   {GL_VIEW_CLASS_32_BITS, GL_RGBA8I},
117
   {GL_VIEW_CLASS_32_BITS, GL_RG16I},
118
   {GL_VIEW_CLASS_32_BITS, GL_R32I},
119
   {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2},
120
   {GL_VIEW_CLASS_32_BITS, GL_RGBA8},
121
   {GL_VIEW_CLASS_32_BITS, GL_RG16},
122
   {GL_VIEW_CLASS_32_BITS, GL_RGBA8_SNORM},
123
   {GL_VIEW_CLASS_32_BITS, GL_RG16_SNORM},
124
   {GL_VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8},
125
   {GL_VIEW_CLASS_32_BITS, GL_RGB9_E5},
126
   {GL_VIEW_CLASS_24_BITS, GL_RGB8},
127
   {GL_VIEW_CLASS_24_BITS, GL_RGB8_SNORM},
128
   {GL_VIEW_CLASS_24_BITS, GL_SRGB8},
129
   {GL_VIEW_CLASS_24_BITS, GL_RGB8UI},
130
   {GL_VIEW_CLASS_24_BITS, GL_RGB8I},
131
   {GL_VIEW_CLASS_16_BITS, GL_R16F},
132
   {GL_VIEW_CLASS_16_BITS, GL_RG8UI},
133
   {GL_VIEW_CLASS_16_BITS, GL_R16UI},
134
   {GL_VIEW_CLASS_16_BITS, GL_RG8I},
135
   {GL_VIEW_CLASS_16_BITS, GL_R16I},
136
   {GL_VIEW_CLASS_16_BITS, GL_RG8},
137
   {GL_VIEW_CLASS_16_BITS, GL_R16},
138
   {GL_VIEW_CLASS_16_BITS, GL_RG8_SNORM},
139
   {GL_VIEW_CLASS_16_BITS, GL_R16_SNORM},
140
   {GL_VIEW_CLASS_8_BITS, GL_R8UI},
141
   {GL_VIEW_CLASS_8_BITS, GL_R8I},
142
   {GL_VIEW_CLASS_8_BITS, GL_R8},
143
   {GL_VIEW_CLASS_8_BITS, GL_R8_SNORM},
144
   {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_RED_RGTC1},
145
   {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1},
146
   {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_RG_RGTC2},
147
   {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2},
148
   {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB},
149
   {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB},
150
   {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB},
151
   {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB},
152
};
153
 
154
static const struct internal_format_class_info s3tc_compatible_internal_formats[] = {
155
   {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT},
156
   {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT},
157
   {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT},
158
   {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT},
159
   {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT},
160
   {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT},
161
   {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT},
162
   {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT},
163
};
164
 
165
/**
166
 * Lookup format view class based on internalformat
167
 * \return VIEW_CLASS if internalformat found in table, false otherwise.
168
 */
169
static GLenum
170
lookup_view_class(struct gl_context *ctx, GLenum internalformat)
171
{
172
   GLuint i;
173
 
174
   for (i = 0; i < ARRAY_SIZE(compatible_internal_formats); i++) {
175
      if (compatible_internal_formats[i].internal_format == internalformat)
176
         return compatible_internal_formats[i].view_class;
177
   }
178
 
179
   if (ctx->Extensions.EXT_texture_compression_s3tc && ctx->Extensions.EXT_texture_sRGB) {
180
      for (i = 0; i < ARRAY_SIZE(s3tc_compatible_internal_formats); i++) {
181
         if (s3tc_compatible_internal_formats[i].internal_format == internalformat)
182
            return s3tc_compatible_internal_formats[i].view_class;
183
      }
184
   }
185
   return GL_FALSE;
186
}
187
 
188
/**
189
 * Initialize new texture's gl_texture_image structures. Will not call driver
190
 * to allocate new space, simply record relevant layer, face, format, etc.
191
 * \return GL_FALSE if any error, GL_TRUE otherwise.
192
 */
193
static GLboolean
194
initialize_texture_fields(struct gl_context *ctx,
195
                          GLenum target,
196
                          struct gl_texture_object *texObj,
197
                          GLint levels,
198
                          GLsizei width, GLsizei height, GLsizei depth,
199
                          GLenum internalFormat, mesa_format texFormat)
200
{
201
   const GLuint numFaces = _mesa_num_tex_faces(target);
202
   GLint level, levelWidth = width, levelHeight = height, levelDepth = depth;
203
   GLuint face;
204
 
205
   /* Pretend we are bound to initialize the gl_texture_image structs */
206
   texObj->Target = target;
207
 
208
   /* Set up all the texture object's gl_texture_images */
209
   for (level = 0; level < levels; level++) {
210
      for (face = 0; face < numFaces; face++) {
211
         struct gl_texture_image *texImage;
212
         GLenum faceTarget = target;
213
 
214
         if (target == GL_TEXTURE_CUBE_MAP)
215
            faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
216
 
217
         texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, level);
218
 
219
         if (!texImage) {
220
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage");
221
            return GL_FALSE;
222
         }
223
 
224
         _mesa_init_teximage_fields(ctx, texImage,
225
                                    levelWidth, levelHeight, levelDepth,
226
                                    0, internalFormat, texFormat);
227
      }
228
 
229
      _mesa_next_mipmap_level_size(target, 0, levelWidth, levelHeight, levelDepth,
230
                                   &levelWidth, &levelHeight, &levelDepth);
231
   }
232
 
233
   /* "unbind" */
234
   texObj->Target = 0;
235
 
236
   return GL_TRUE;
237
}
238
 
239
#define RETURN_IF_SUPPORTED(t) do {		\
240
   if (newTarget == GL_ ## t)                   \
241
      return true;				\
242
} while (0)
243
 
244
/**
245
 * Check for compatible target
246
 * If an error is found, record it with _mesa_error()
247
 * \return false if any error, true otherwise.
248
 */
249
static bool
250
target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget)
251
{
252
   /*
253
    * From ARB_texture_view spec:
254
   ---------------------------------------------------------------------------------------------------------
255
   | Original target              | Valid new targets |
256
   ---------------------------------------------------------------------------------------------------------
257
   | TEXTURE_1D                   | TEXTURE_1D, TEXTURE_1D_ARRAY |
258
   | ------------------------------------------------------------------------------------------------------- |
259
   | TEXTURE_2D                   | TEXTURE_2D, TEXTURE_2D_ARRAY |
260
   | ------------------------------------------------------------------------------------------------------- |
261
   | TEXTURE_3D                   | TEXTURE_3D |
262
   | ------------------------------------------------------------------------------------------------------- |
263
   | TEXTURE_CUBE_MAP             | TEXTURE_CUBE_MAP, TEXTURE_2D, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY |
264
   | ------------------------------------------------------------------------------------------------------- |
265
   | TEXTURE_RECTANGLE            | TEXTURE_RECTANGLE |
266
   | ------------------------------------------------------------------------------------------------------- |
267
   | TEXTURE_BUFFER               |  |
268
   | ------------------------------------------------------------------------------------------------------- |
269
   | TEXTURE_1D_ARRAY             | TEXTURE_1D_ARRAY, TEXTURE_1D |
270
   | ------------------------------------------------------------------------------------------------------- |
271
   | TEXTURE_2D_ARRAY             | TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP, TEXTURE_CUBE_MAP_ARRAY |
272
   | ------------------------------------------------------------------------------------------------------- |
273
   | TEXTURE_CUBE_MAP_ARRAY       | TEXTURE_CUBE_MAP_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP |
274
   | ------------------------------------------------------------------------------------------------------- |
275
   | TEXTURE_2D_MULTISAMPLE       | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY |
276
   | ------------------------------------------------------------------------------------------------------- |
277
   | TEXTURE_2D_MULTISAMPLE_ARRAY | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY |
278
   ---------------------------------------------------------------------------------------------------------
279
    */
280
 
281
   switch (origTarget) {
282
   case GL_TEXTURE_1D:
283
   case GL_TEXTURE_1D_ARRAY:
284
      RETURN_IF_SUPPORTED(TEXTURE_1D);
285
      RETURN_IF_SUPPORTED(TEXTURE_1D_ARRAY);
286
      break;
287
   case GL_TEXTURE_2D:
288
      RETURN_IF_SUPPORTED(TEXTURE_2D);
289
      RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY);
290
      break;
291
   case GL_TEXTURE_3D:
292
      RETURN_IF_SUPPORTED(TEXTURE_3D);
293
      break;
294
   case GL_TEXTURE_RECTANGLE:
295
      RETURN_IF_SUPPORTED(TEXTURE_RECTANGLE);
296
      break;
297
   case GL_TEXTURE_CUBE_MAP:
298
   case GL_TEXTURE_2D_ARRAY:
299
   case GL_TEXTURE_CUBE_MAP_ARRAY:
300
      RETURN_IF_SUPPORTED(TEXTURE_2D);
301
      RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY);
302
      RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP);
303
      RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP_ARRAY);
304
      break;
305
   case GL_TEXTURE_2D_MULTISAMPLE:
306
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
307
      RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE);
308
      RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE_ARRAY);
309
      break;
310
   }
311
   _mesa_error(ctx, GL_INVALID_OPERATION,
312
               "glTextureView(illegal target=%s)",
313
               _mesa_lookup_enum_by_nr(newTarget));
314
   return false;
315
}
316
#undef RETURN_IF_SUPPORTED
317
 
318
/**
319
 * Check for compatible format
320
 * If an error is found, record it with _mesa_error()
321
 * \return false if any error, true otherwise.
322
 */
323
GLboolean
324
_mesa_texture_view_compatible_format(struct gl_context *ctx,
325
                                     GLenum origInternalFormat,
326
                                     GLenum newInternalFormat)
327
{
328
   unsigned int origViewClass, newViewClass;
329
 
330
   /* The two textures' internal formats must be compatible according to
331
    * Table 3.X.2 (Compatible internal formats for TextureView)
332
    * if the internal format exists in that table the view class must match.
333
    * The internal formats must be identical if not in that table,
334
    * or an INVALID_OPERATION error is generated.
335
    */
336
   if (origInternalFormat == newInternalFormat)
337
      return GL_TRUE;
338
 
339
   origViewClass = lookup_view_class(ctx, origInternalFormat);
340
   newViewClass = lookup_view_class(ctx, newInternalFormat);
341
   if ((origViewClass == newViewClass) && origViewClass != false)
342
      return GL_TRUE;
343
 
344
   return GL_FALSE;
345
}
346
/**
347
 * Helper function for TexStorage and teximagemultisample to set immutable
348
 * texture state needed by ARB_texture_view.
349
 */
350
void
351
_mesa_set_texture_view_state(struct gl_context *ctx,
352
                             struct gl_texture_object *texObj,
353
                             GLenum target, GLuint levels)
354
{
355
   struct gl_texture_image *texImage;
356
 
357
   /* Get a reference to what will become this View's base level */
358
   texImage = _mesa_select_tex_image(texObj, target, 0);
359
 
360
   /* When an immutable texture is created via glTexStorage or glTexImageMultisample,
361
    * TEXTURE_IMMUTABLE_FORMAT becomes TRUE.
362
    * TEXTURE_IMMUTABLE_LEVELS and TEXTURE_VIEW_NUM_LEVELS become levels.
363
    * If the texture target is TEXTURE_1D_ARRAY then
364
    * TEXTURE_VIEW_NUM_LAYERS becomes height.
365
    * If the texture target is TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY,
366
    * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes depth.
367
    * If the texture target is TEXTURE_CUBE_MAP, then
368
    * TEXTURE_VIEW_NUM_LAYERS becomes 6.
369
    * For any other texture target, TEXTURE_VIEW_NUM_LAYERS becomes 1.
370
    *
371
    * ARB_texture_multisample: Multisample textures do
372
    * not have multiple image levels.
373
    */
374
 
375
   texObj->Immutable = GL_TRUE;
376
   texObj->ImmutableLevels = levels;
377
   texObj->MinLevel = 0;
378
   texObj->NumLevels = levels;
379
   texObj->MinLayer = 0;
380
   texObj->NumLayers = 1;
381
   switch (target) {
382
   case GL_TEXTURE_1D_ARRAY:
383
      texObj->NumLayers = texImage->Height;
384
      break;
385
 
386
   case GL_TEXTURE_2D_MULTISAMPLE:
387
      texObj->NumLevels = 1;
388
      texObj->ImmutableLevels = 1;
389
      break;
390
 
391
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
392
      texObj->NumLevels = 1;
393
      texObj->ImmutableLevels = 1;
394
      /* fall through to set NumLayers */
395
 
396
   case GL_TEXTURE_2D_ARRAY:
397
   case GL_TEXTURE_CUBE_MAP_ARRAY:
398
      texObj->NumLayers = texImage->Depth;
399
      break;
400
 
401
   case GL_TEXTURE_CUBE_MAP:
402
      texObj->NumLayers = 6;
403
      break;
404
 
405
   }
406
}
407
 
408
/**
409
 * glTextureView (ARB_texture_view)
410
 * If an error is found, record it with _mesa_error()
411
 * \return none.
412
 */
413
void GLAPIENTRY
414
_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
415
                  GLenum internalformat,
416
                  GLuint minlevel, GLuint numlevels,
417
                  GLuint minlayer, GLuint numlayers)
418
{
419
   struct gl_texture_object *texObj;
420
   struct gl_texture_object *origTexObj;
421
   struct gl_texture_image *origTexImage;
422
   GLuint newViewMinLevel, newViewMinLayer;
423
   GLuint newViewNumLevels, newViewNumLayers;
424
   GLsizei width, height, depth;
425
   mesa_format texFormat;
426
   GLboolean sizeOK, dimensionsOK;
427
   GLenum faceTarget;
428
 
429
   GET_CURRENT_CONTEXT(ctx);
430
 
431
   if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
432
      _mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n",
433
                  texture, _mesa_lookup_enum_by_nr(target), origtexture,
434
                  _mesa_lookup_enum_by_nr(internalformat),
435
                  minlevel, numlevels, minlayer, numlayers);
436
 
437
   if (origtexture == 0) {
438
      _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture);
439
      return;
440
   }
441
 
442
   /* Need original texture information to validate arguments */
443
   origTexObj = _mesa_lookup_texture(ctx, origtexture);
444
 
445
   /* If  is not the name of a texture, INVALID_VALUE is generated. */
446
   if (!origTexObj) {
447
      _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", origtexture);
448
      return;
449
   }
450
 
451
   /* If 's TEXTURE_IMMUTABLE_FORMAT value is not TRUE,
452
    * INVALID_OPERATION is generated.
453
    */
454
   if (!origTexObj->Immutable) {
455
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture not immutable)");
456
      return;
457
   }
458
 
459
   /* If  is 0, INVALID_VALUE is generated. */
460
   if (texture == 0) {
461
      _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(texture = 0)");
462
      return;
463
   }
464
 
465
   /* If  is not a valid name returned by GenTextures,
466
    * the error INVALID_OPERATION is generated.
467
    */
468
   texObj = _mesa_lookup_texture(ctx, texture);
469
   if (texObj == NULL) {
470
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u non-gen name)", texture);
471
      return;
472
   }
473
 
474
   /* If  has already been bound and given a target, then
475
    * the error INVALID_OPERATION is generated.
476
    */
477
   if (texObj->Target) {
478
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(texture = %u already bound)", texture);
479
      return;
480
   }
481
 
482
   /* Check for compatible target */
483
   if (!target_valid(ctx, origTexObj->Target, target)) {
484
      return; /* error was recorded */
485
   }
486
 
487
   /* minlevel and minlayer are relative to the view of origtexture
488
    * If minlevel or minlayer is greater than level or layer, respectively,
489
    * of origtexture return INVALID_VALUE.
490
    */
491
   newViewMinLevel = origTexObj->MinLevel + minlevel;
492
   newViewMinLayer = origTexObj->MinLayer + minlayer;
493
   if (newViewMinLevel >= (origTexObj->MinLevel + origTexObj->NumLevels)) {
494
      _mesa_error(ctx, GL_INVALID_VALUE,
495
                  "glTextureView(new minlevel (%d) > orig minlevel (%d) + orig numlevels (%d))",
496
                  newViewMinLevel, origTexObj->MinLevel, origTexObj->NumLevels);
497
      return;
498
   }
499
 
500
   if (newViewMinLayer >= (origTexObj->MinLayer + origTexObj->NumLayers)) {
501
      _mesa_error(ctx, GL_INVALID_VALUE,
502
                  "glTextureView(new minlayer (%d) > orig minlayer (%d) + orig numlayers (%d))",
503
                  newViewMinLayer, origTexObj->MinLayer, origTexObj->NumLayers);
504
      return;
505
   }
506
 
507
   if (!_mesa_texture_view_compatible_format(ctx,
508
                                             origTexObj->Image[0][0]->InternalFormat,
509
                                             internalformat)) {
510
      _mesa_error(ctx, GL_INVALID_OPERATION,
511
                  "glTextureView(internalformat %s not compatible with origtexture %s)",
512
                  _mesa_lookup_enum_by_nr(internalformat),
513
                  _mesa_lookup_enum_by_nr(origTexObj->Image[0][0]->InternalFormat));
514
      return;
515
   }
516
 
517
   texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
518
                                           internalformat, GL_NONE, GL_NONE);
519
   assert(texFormat != MESA_FORMAT_NONE);
520
   if (texFormat == MESA_FORMAT_NONE) return;
521
 
522
   newViewNumLevels = MIN2(numlevels, origTexObj->NumLevels - minlevel);
523
   newViewNumLayers = MIN2(numlayers, origTexObj->NumLayers - minlayer);
524
 
525
   faceTarget = origTexObj->Target;
526
   if (faceTarget == GL_TEXTURE_CUBE_MAP)
527
      faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + minlayer;
528
 
529
   /* Get a reference to what will become this View's base level */
530
   origTexImage = _mesa_select_tex_image(origTexObj, faceTarget, minlevel);
531
   width = origTexImage->Width;
532
   height = origTexImage->Height;
533
   depth = origTexImage->Depth;
534
 
535
   /* Adjust width, height, depth to be appropriate for new target */
536
   switch (target) {
537
   case GL_TEXTURE_1D:
538
      height = 1;
539
      break;
540
 
541
   case GL_TEXTURE_3D:
542
      break;
543
 
544
   case GL_TEXTURE_1D_ARRAY:
545
      height = (GLsizei) newViewNumLayers;
546
      break;
547
 
548
   case GL_TEXTURE_2D:
549
   case GL_TEXTURE_2D_MULTISAMPLE:
550
   case GL_TEXTURE_RECTANGLE:
551
   case GL_TEXTURE_CUBE_MAP:
552
      depth = 1;
553
      break;
554
 
555
   case GL_TEXTURE_2D_ARRAY:
556
   case GL_TEXTURE_CUBE_MAP_ARRAY:
557
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
558
      depth = newViewNumLayers;
559
      break;
560
   }
561
 
562
   /* If the dimensions of the original texture are larger than the maximum
563
    * supported dimensions of the new target, the error INVALID_OPERATION is
564
    * generated. For example, if the original texture has a TEXTURE_2D_ARRAY
565
    * target and its width is greater than MAX_CUBE_MAP_TEXTURE_SIZE, an error
566
    * will be generated if TextureView is called to create a TEXTURE_CUBE_MAP
567
    * view.
568
    */
569
   dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
570
                                                 width, height, depth, 0);
571
   if (!dimensionsOK) {
572
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid width or height or depth)");
573
      return;
574
   }
575
 
576
   sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, texFormat,
577
                                          width, height, depth, 0);
578
   if (!sizeOK) {
579
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid texture size)");
580
      return;
581
   }
582
 
583
   /* If  is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE,
584
    * or TEXTURE_2D_MULTISAMPLE and  does not equal 1, the error
585
    * INVALID_VALUE is generated.
586
    */
587
   switch (target) {
588
   case GL_TEXTURE_1D:
589
   case GL_TEXTURE_2D:
590
   case GL_TEXTURE_3D:
591
   case GL_TEXTURE_RECTANGLE:
592
   case GL_TEXTURE_2D_MULTISAMPLE:
593
      if (numlayers != 1) {
594
         _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)", numlayers);
595
         return;
596
      }
597
      break;
598
 
599
   case GL_TEXTURE_CUBE_MAP:
600
      /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped 
601
       * must be equal to 6.
602
       */
603
      if (newViewNumLayers != 6) {
604
         _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(clamped numlayers %d != 6)",
605
                     newViewNumLayers);
606
         return;
607
      }
608
      break;
609
 
610
   case GL_TEXTURE_CUBE_MAP_ARRAY:
611
      /* If the new texture's target is TEXTURE_CUBE_MAP_ARRAY,
612
       * then  counts layer-faces rather than layers,
613
       * and the clamped  must be a multiple of 6.
614
       * Otherwise, the error INVALID_VALUE is generated.
615
       */
616
      if ((newViewNumLayers % 6) != 0) {
617
         _mesa_error(ctx, GL_INVALID_VALUE,
618
                     "glTextureView(clamped numlayers %d is not a multiple of 6)",
619
                     newViewNumLayers);
620
         return;
621
      }
622
      break;
623
   }
624
 
625
   /* If the new texture's target is TEXTURE_CUBE_MAP or
626
    * TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's
627
    * levels must be equal otherwise the error INVALID_OPERATION is generated.
628
    */
629
   if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) &&
630
       (origTexImage->Width != origTexImage->Height)) {
631
      _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(origtexture width (%d) != height (%d))",
632
                  origTexImage->Width, origTexImage->Height);
633
      return;
634
   }
635
 
636
   /* When the original texture's target is TEXTURE_CUBE_MAP, the layer
637
    * parameters are interpreted in the same order as if it were a
638
    * TEXTURE_CUBE_MAP_ARRAY with 6 layer-faces.
639
    */
640
 
641
   /* If the internal format does not exactly match the internal format of the
642
    * original texture, the contents of the memory are reinterpreted in the
643
    * same manner as for image bindings described in
644
    * section 3.9.20 (Texture Image Loads and Stores).
645
    */
646
 
647
   /* TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL are interpreted
648
    * relative to the view and not relative to the original data store.
649
    */
650
 
651
   if (!initialize_texture_fields(ctx, target, texObj, newViewNumLevels,
652
                                  width, height, depth,
653
                                  internalformat, texFormat)) {
654
      return; /* Already recorded error */
655
   }
656
 
657
   texObj->MinLevel = newViewMinLevel;
658
   texObj->MinLayer = newViewMinLayer;
659
   texObj->NumLevels = newViewNumLevels;
660
   texObj->NumLayers = newViewNumLayers;
661
   texObj->Immutable = GL_TRUE;
662
   texObj->ImmutableLevels = origTexObj->ImmutableLevels;
663
   texObj->Target = target;
664
 
665
   if (ctx->Driver.TextureView != NULL && !ctx->Driver.TextureView(ctx, texObj, origTexObj)) {
666
      return; /* driver recorded error */
667
   }
668
}