Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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 <courtney@lunarg.com>
  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               | <none> |
  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 <origtexture> 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 <origtexture>'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 <texture> 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 <texture> 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 <texture> 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 <target> is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE,
  584.     * or TEXTURE_2D_MULTISAMPLE and <numlayers> 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 <numlayers>
  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 <numlayers> counts layer-faces rather than layers,
  613.        * and the clamped <numlayers> 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. }
  669.