Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**
  2.  * \file texobj.c
  3.  * Texture object management.
  4.  */
  5.  
  6. /*
  7.  * Mesa 3-D graphics library
  8.  *
  9.  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
  10.  *
  11.  * Permission is hereby granted, free of charge, to any person obtaining a
  12.  * copy of this software and associated documentation files (the "Software"),
  13.  * to deal in the Software without restriction, including without limitation
  14.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  15.  * and/or sell copies of the Software, and to permit persons to whom the
  16.  * Software is furnished to do so, subject to the following conditions:
  17.  *
  18.  * The above copyright notice and this permission notice shall be included
  19.  * in all copies or substantial portions of the Software.
  20.  *
  21.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  22.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  24.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  25.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  26.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  27.  * OTHER DEALINGS IN THE SOFTWARE.
  28.  */
  29.  
  30.  
  31. #include "bufferobj.h"
  32. #include "colortab.h"
  33. #include "context.h"
  34. #include "enums.h"
  35. #include "fbobject.h"
  36. #include "formats.h"
  37. #include "hash.h"
  38. #include "imports.h"
  39. #include "macros.h"
  40. #include "teximage.h"
  41. #include "texobj.h"
  42. #include "texstate.h"
  43. #include "mtypes.h"
  44. #include "program/prog_instruction.h"
  45.  
  46.  
  47.  
  48. /**********************************************************************/
  49. /** \name Internal functions */
  50. /*@{*/
  51.  
  52.  
  53. /**
  54.  * Return the gl_texture_object for a given ID.
  55.  */
  56. struct gl_texture_object *
  57. _mesa_lookup_texture(struct gl_context *ctx, GLuint id)
  58. {
  59.    return (struct gl_texture_object *)
  60.       _mesa_HashLookup(ctx->Shared->TexObjects, id);
  61. }
  62.  
  63.  
  64.  
  65. /**
  66.  * Allocate and initialize a new texture object.  But don't put it into the
  67.  * texture object hash table.
  68.  *
  69.  * Called via ctx->Driver.NewTextureObject, unless overridden by a device
  70.  * driver.
  71.  *
  72.  * \param shared the shared GL state structure to contain the texture object
  73.  * \param name integer name for the texture object
  74.  * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
  75.  * GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV.  zero is ok for the sake
  76.  * of GenTextures()
  77.  *
  78.  * \return pointer to new texture object.
  79.  */
  80. struct gl_texture_object *
  81. _mesa_new_texture_object( struct gl_context *ctx, GLuint name, GLenum target )
  82. {
  83.    struct gl_texture_object *obj;
  84.    (void) ctx;
  85.    obj = MALLOC_STRUCT(gl_texture_object);
  86.    _mesa_initialize_texture_object(ctx, obj, name, target);
  87.    return obj;
  88. }
  89.  
  90.  
  91. /**
  92.  * Initialize a new texture object to default values.
  93.  * \param obj  the texture object
  94.  * \param name  the texture name
  95.  * \param target  the texture target
  96.  */
  97. void
  98. _mesa_initialize_texture_object( struct gl_context *ctx,
  99.                                  struct gl_texture_object *obj,
  100.                                  GLuint name, GLenum target )
  101. {
  102.    ASSERT(target == 0 ||
  103.           target == GL_TEXTURE_1D ||
  104.           target == GL_TEXTURE_2D ||
  105.           target == GL_TEXTURE_3D ||
  106.           target == GL_TEXTURE_CUBE_MAP_ARB ||
  107.           target == GL_TEXTURE_RECTANGLE_NV ||
  108.           target == GL_TEXTURE_1D_ARRAY_EXT ||
  109.           target == GL_TEXTURE_2D_ARRAY_EXT ||
  110.           target == GL_TEXTURE_EXTERNAL_OES ||
  111.           target == GL_TEXTURE_CUBE_MAP_ARRAY ||
  112.           target == GL_TEXTURE_BUFFER ||
  113.           target == GL_TEXTURE_2D_MULTISAMPLE ||
  114.           target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
  115.  
  116.    memset(obj, 0, sizeof(*obj));
  117.    /* init the non-zero fields */
  118.    _glthread_INIT_MUTEX(obj->Mutex);
  119.    obj->RefCount = 1;
  120.    obj->Name = name;
  121.    obj->Target = target;
  122.    obj->Priority = 1.0F;
  123.    obj->BaseLevel = 0;
  124.    obj->MaxLevel = 1000;
  125.  
  126.    /* must be one; no support for (YUV) planes in separate buffers */
  127.    obj->RequiredTextureImageUnits = 1;
  128.  
  129.    /* sampler state */
  130.    if (target == GL_TEXTURE_RECTANGLE_NV ||
  131.        target == GL_TEXTURE_EXTERNAL_OES) {
  132.       obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
  133.       obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
  134.       obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
  135.       obj->Sampler.MinFilter = GL_LINEAR;
  136.    }
  137.    else {
  138.       obj->Sampler.WrapS = GL_REPEAT;
  139.       obj->Sampler.WrapT = GL_REPEAT;
  140.       obj->Sampler.WrapR = GL_REPEAT;
  141.       obj->Sampler.MinFilter = GL_NEAREST_MIPMAP_LINEAR;
  142.    }
  143.    obj->Sampler.MagFilter = GL_LINEAR;
  144.    obj->Sampler.MinLod = -1000.0;
  145.    obj->Sampler.MaxLod = 1000.0;
  146.    obj->Sampler.LodBias = 0.0;
  147.    obj->Sampler.MaxAnisotropy = 1.0;
  148.    obj->Sampler.CompareMode = GL_NONE;         /* ARB_shadow */
  149.    obj->Sampler.CompareFunc = GL_LEQUAL;       /* ARB_shadow */
  150.    obj->DepthMode = ctx->API == API_OPENGL_CORE ? GL_RED : GL_LUMINANCE;
  151.    obj->Sampler.CubeMapSeamless = GL_FALSE;
  152.    obj->Swizzle[0] = GL_RED;
  153.    obj->Swizzle[1] = GL_GREEN;
  154.    obj->Swizzle[2] = GL_BLUE;
  155.    obj->Swizzle[3] = GL_ALPHA;
  156.    obj->_Swizzle = SWIZZLE_NOOP;
  157.    obj->Sampler.sRGBDecode = GL_DECODE_EXT;
  158.    obj->BufferObjectFormat = GL_R8;
  159.    obj->_BufferObjectFormat = MESA_FORMAT_R8;
  160. }
  161.  
  162.  
  163. /**
  164.  * Some texture initialization can't be finished until we know which
  165.  * target it's getting bound to (GL_TEXTURE_1D/2D/etc).
  166.  */
  167. static void
  168. finish_texture_init(struct gl_context *ctx, GLenum target,
  169.                     struct gl_texture_object *obj)
  170. {
  171.    GLenum filter = GL_LINEAR;
  172.    assert(obj->Target == 0);
  173.  
  174.    switch (target) {
  175.       case GL_TEXTURE_2D_MULTISAMPLE:
  176.       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
  177.          filter = GL_NEAREST;
  178.          /* fallthrough */
  179.  
  180.       case GL_TEXTURE_RECTANGLE_NV:
  181.       case GL_TEXTURE_EXTERNAL_OES:
  182.          /* have to init wrap and filter state here - kind of klunky */
  183.          obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
  184.          obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
  185.          obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
  186.          obj->Sampler.MinFilter = filter;
  187.          obj->Sampler.MagFilter = filter;
  188.          if (ctx->Driver.TexParameter) {
  189.             static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
  190.             const GLfloat fparam_filter[1] = {(GLfloat) filter};
  191.             ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
  192.             ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
  193.             ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
  194.             ctx->Driver.TexParameter(ctx, target, obj,
  195.                   GL_TEXTURE_MIN_FILTER, fparam_filter);
  196.             ctx->Driver.TexParameter(ctx, target, obj,
  197.                   GL_TEXTURE_MAG_FILTER, fparam_filter);
  198.          }
  199.          break;
  200.  
  201.       default:
  202.          /* nothing needs done */
  203.          break;
  204.    }
  205. }
  206.  
  207.  
  208. /**
  209.  * Deallocate a texture object struct.  It should have already been
  210.  * removed from the texture object pool.
  211.  * Called via ctx->Driver.DeleteTexture() if not overriden by a driver.
  212.  *
  213.  * \param shared the shared GL state to which the object belongs.
  214.  * \param texObj the texture object to delete.
  215.  */
  216. void
  217. _mesa_delete_texture_object(struct gl_context *ctx,
  218.                             struct gl_texture_object *texObj)
  219. {
  220.    GLuint i, face;
  221.  
  222.    /* Set Target to an invalid value.  With some assertions elsewhere
  223.     * we can try to detect possible use of deleted textures.
  224.     */
  225.    texObj->Target = 0x99;
  226.  
  227.    /* free the texture images */
  228.    for (face = 0; face < 6; face++) {
  229.       for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
  230.          if (texObj->Image[face][i]) {
  231.             ctx->Driver.DeleteTextureImage(ctx, texObj->Image[face][i]);
  232.          }
  233.       }
  234.    }
  235.  
  236.    _mesa_reference_buffer_object(ctx, &texObj->BufferObject, NULL);
  237.  
  238.    /* destroy the mutex -- it may have allocated memory (eg on bsd) */
  239.    _glthread_DESTROY_MUTEX(texObj->Mutex);
  240.  
  241.    /* free this object */
  242.    free(texObj);
  243. }
  244.  
  245.  
  246.  
  247. /**
  248.  * Copy texture object state from one texture object to another.
  249.  * Use for glPush/PopAttrib.
  250.  *
  251.  * \param dest destination texture object.
  252.  * \param src source texture object.
  253.  */
  254. void
  255. _mesa_copy_texture_object( struct gl_texture_object *dest,
  256.                            const struct gl_texture_object *src )
  257. {
  258.    dest->Target = src->Target;
  259.    dest->Name = src->Name;
  260.    dest->Priority = src->Priority;
  261.    dest->Sampler.BorderColor.f[0] = src->Sampler.BorderColor.f[0];
  262.    dest->Sampler.BorderColor.f[1] = src->Sampler.BorderColor.f[1];
  263.    dest->Sampler.BorderColor.f[2] = src->Sampler.BorderColor.f[2];
  264.    dest->Sampler.BorderColor.f[3] = src->Sampler.BorderColor.f[3];
  265.    dest->Sampler.WrapS = src->Sampler.WrapS;
  266.    dest->Sampler.WrapT = src->Sampler.WrapT;
  267.    dest->Sampler.WrapR = src->Sampler.WrapR;
  268.    dest->Sampler.MinFilter = src->Sampler.MinFilter;
  269.    dest->Sampler.MagFilter = src->Sampler.MagFilter;
  270.    dest->Sampler.MinLod = src->Sampler.MinLod;
  271.    dest->Sampler.MaxLod = src->Sampler.MaxLod;
  272.    dest->Sampler.LodBias = src->Sampler.LodBias;
  273.    dest->BaseLevel = src->BaseLevel;
  274.    dest->MaxLevel = src->MaxLevel;
  275.    dest->Sampler.MaxAnisotropy = src->Sampler.MaxAnisotropy;
  276.    dest->Sampler.CompareMode = src->Sampler.CompareMode;
  277.    dest->Sampler.CompareFunc = src->Sampler.CompareFunc;
  278.    dest->Sampler.CubeMapSeamless = src->Sampler.CubeMapSeamless;
  279.    dest->DepthMode = src->DepthMode;
  280.    dest->Sampler.sRGBDecode = src->Sampler.sRGBDecode;
  281.    dest->_MaxLevel = src->_MaxLevel;
  282.    dest->_MaxLambda = src->_MaxLambda;
  283.    dest->GenerateMipmap = src->GenerateMipmap;
  284.    dest->_BaseComplete = src->_BaseComplete;
  285.    dest->_MipmapComplete = src->_MipmapComplete;
  286.    COPY_4V(dest->Swizzle, src->Swizzle);
  287.    dest->_Swizzle = src->_Swizzle;
  288.  
  289.    dest->RequiredTextureImageUnits = src->RequiredTextureImageUnits;
  290. }
  291.  
  292.  
  293. /**
  294.  * Free all texture images of the given texture object.
  295.  *
  296.  * \param ctx GL context.
  297.  * \param t texture object.
  298.  *
  299.  * \sa _mesa_clear_texture_image().
  300.  */
  301. void
  302. _mesa_clear_texture_object(struct gl_context *ctx,
  303.                            struct gl_texture_object *texObj)
  304. {
  305.    GLuint i, j;
  306.  
  307.    if (texObj->Target == 0)
  308.       return;
  309.  
  310.    for (i = 0; i < MAX_FACES; i++) {
  311.       for (j = 0; j < MAX_TEXTURE_LEVELS; j++) {
  312.          struct gl_texture_image *texImage = texObj->Image[i][j];
  313.          if (texImage)
  314.             _mesa_clear_texture_image(ctx, texImage);
  315.       }
  316.    }
  317. }
  318.  
  319.  
  320. /**
  321.  * Check if the given texture object is valid by examining its Target field.
  322.  * For debugging only.
  323.  */
  324. static GLboolean
  325. valid_texture_object(const struct gl_texture_object *tex)
  326. {
  327.    switch (tex->Target) {
  328.    case 0:
  329.    case GL_TEXTURE_1D:
  330.    case GL_TEXTURE_2D:
  331.    case GL_TEXTURE_3D:
  332.    case GL_TEXTURE_CUBE_MAP_ARB:
  333.    case GL_TEXTURE_RECTANGLE_NV:
  334.    case GL_TEXTURE_1D_ARRAY_EXT:
  335.    case GL_TEXTURE_2D_ARRAY_EXT:
  336.    case GL_TEXTURE_BUFFER:
  337.    case GL_TEXTURE_EXTERNAL_OES:
  338.    case GL_TEXTURE_CUBE_MAP_ARRAY:
  339.    case GL_TEXTURE_2D_MULTISAMPLE:
  340.    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
  341.       return GL_TRUE;
  342.    case 0x99:
  343.       _mesa_problem(NULL, "invalid reference to a deleted texture object");
  344.       return GL_FALSE;
  345.    default:
  346.       _mesa_problem(NULL, "invalid texture object Target 0x%x, Id = %u",
  347.                     tex->Target, tex->Name);
  348.       return GL_FALSE;
  349.    }
  350. }
  351.  
  352.  
  353. /**
  354.  * Reference (or unreference) a texture object.
  355.  * If '*ptr', decrement *ptr's refcount (and delete if it becomes zero).
  356.  * If 'tex' is non-null, increment its refcount.
  357.  * This is normally only called from the _mesa_reference_texobj() macro
  358.  * when there's a real pointer change.
  359.  */
  360. void
  361. _mesa_reference_texobj_(struct gl_texture_object **ptr,
  362.                         struct gl_texture_object *tex)
  363. {
  364.    assert(ptr);
  365.  
  366.    if (*ptr) {
  367.       /* Unreference the old texture */
  368.       GLboolean deleteFlag = GL_FALSE;
  369.       struct gl_texture_object *oldTex = *ptr;
  370.  
  371.       ASSERT(valid_texture_object(oldTex));
  372.       (void) valid_texture_object; /* silence warning in release builds */
  373.  
  374.       _glthread_LOCK_MUTEX(oldTex->Mutex);
  375.       ASSERT(oldTex->RefCount > 0);
  376.       oldTex->RefCount--;
  377.  
  378.       deleteFlag = (oldTex->RefCount == 0);
  379.       _glthread_UNLOCK_MUTEX(oldTex->Mutex);
  380.  
  381.       if (deleteFlag) {
  382.          GET_CURRENT_CONTEXT(ctx);
  383.          if (ctx)
  384.             ctx->Driver.DeleteTexture(ctx, oldTex);
  385.          else
  386.             _mesa_problem(NULL, "Unable to delete texture, no context");
  387.       }
  388.  
  389.       *ptr = NULL;
  390.    }
  391.    assert(!*ptr);
  392.  
  393.    if (tex) {
  394.       /* reference new texture */
  395.       ASSERT(valid_texture_object(tex));
  396.       _glthread_LOCK_MUTEX(tex->Mutex);
  397.       if (tex->RefCount == 0) {
  398.          /* this texture's being deleted (look just above) */
  399.          /* Not sure this can every really happen.  Warn if it does. */
  400.          _mesa_problem(NULL, "referencing deleted texture object");
  401.          *ptr = NULL;
  402.       }
  403.       else {
  404.          tex->RefCount++;
  405.          *ptr = tex;
  406.       }
  407.       _glthread_UNLOCK_MUTEX(tex->Mutex);
  408.    }
  409. }
  410.  
  411.  
  412. enum base_mipmap { BASE, MIPMAP };
  413.  
  414.  
  415. /**
  416.  * Mark a texture object as incomplete.  There are actually three kinds of
  417.  * (in)completeness:
  418.  * 1. "base incomplete": the base level of the texture is invalid so no
  419.  *    texturing is possible.
  420.  * 2. "mipmap incomplete": a non-base level of the texture is invalid so
  421.  *    mipmap filtering isn't possible, but non-mipmap filtering is.
  422.  * 3. "texture incompleteness": some combination of texture state and
  423.  *    sampler state renders the texture incomplete.
  424.  *
  425.  * \param t  texture object
  426.  * \param bm  either BASE or MIPMAP to indicate what's incomplete
  427.  * \param fmt...  string describing why it's incomplete (for debugging).
  428.  */
  429. static void
  430. incomplete(struct gl_texture_object *t, enum base_mipmap bm,
  431.            const char *fmt, ...)
  432. {
  433.    if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_TEXTURE) {
  434.       va_list args;
  435.       char s[100];
  436.  
  437.       va_start(args, fmt);
  438.       vsnprintf(s, sizeof(s), fmt, args);
  439.       va_end(args);
  440.  
  441.       _mesa_debug(NULL, "Texture Obj %d incomplete because: %s\n", t->Name, s);
  442.    }
  443.  
  444.    if (bm == BASE)
  445.       t->_BaseComplete = GL_FALSE;
  446.    t->_MipmapComplete = GL_FALSE;
  447. }
  448.  
  449.  
  450. /**
  451.  * Examine a texture object to determine if it is complete.
  452.  *
  453.  * The gl_texture_object::Complete flag will be set to GL_TRUE or GL_FALSE
  454.  * accordingly.
  455.  *
  456.  * \param ctx GL context.
  457.  * \param t texture object.
  458.  *
  459.  * According to the texture target, verifies that each of the mipmaps is
  460.  * present and has the expected size.
  461.  */
  462. void
  463. _mesa_test_texobj_completeness( const struct gl_context *ctx,
  464.                                 struct gl_texture_object *t )
  465. {
  466.    const GLint baseLevel = t->BaseLevel;
  467.    const struct gl_texture_image *baseImage;
  468.    GLint maxLevels = 0;
  469.  
  470.    /* We'll set these to FALSE if tests fail below */
  471.    t->_BaseComplete = GL_TRUE;
  472.    t->_MipmapComplete = GL_TRUE;
  473.  
  474.    if (t->Target == GL_TEXTURE_BUFFER) {
  475.       /* Buffer textures are always considered complete.  The obvious case where
  476.        * they would be incomplete (no BO attached) is actually specced to be
  477.        * undefined rendering results.
  478.        */
  479.       return;
  480.    }
  481.  
  482.    /* Detect cases where the application set the base level to an invalid
  483.     * value.
  484.     */
  485.    if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS)) {
  486.       incomplete(t, BASE, "base level = %d is invalid", baseLevel);
  487.       return;
  488.    }
  489.  
  490.    if (t->MaxLevel < baseLevel) {
  491.       incomplete(t, MIPMAP, "MAX_LEVEL (%d) < BASE_LEVEL (%d)",
  492.                  t->MaxLevel, baseLevel);
  493.       return;
  494.    }
  495.  
  496.    baseImage = t->Image[0][baseLevel];
  497.  
  498.    /* Always need the base level image */
  499.    if (!baseImage) {
  500.       incomplete(t, BASE, "Image[baseLevel=%d] == NULL", baseLevel);
  501.       return;
  502.    }
  503.  
  504.    /* Check width/height/depth for zero */
  505.    if (baseImage->Width == 0 ||
  506.        baseImage->Height == 0 ||
  507.        baseImage->Depth == 0) {
  508.       incomplete(t, BASE, "texture width or height or depth = 0");
  509.       return;
  510.    }
  511.  
  512.    /* Check if the texture values are integer */
  513.    {
  514.       GLenum datatype = _mesa_get_format_datatype(baseImage->TexFormat);
  515.       t->_IsIntegerFormat = datatype == GL_INT || datatype == GL_UNSIGNED_INT;
  516.    }
  517.  
  518.    /* Compute _MaxLevel (the maximum mipmap level we'll sample from given the
  519.     * mipmap image sizes and GL_TEXTURE_MAX_LEVEL state).
  520.     */
  521.    switch (t->Target) {
  522.    case GL_TEXTURE_1D:
  523.    case GL_TEXTURE_1D_ARRAY_EXT:
  524.       maxLevels = ctx->Const.MaxTextureLevels;
  525.       break;
  526.    case GL_TEXTURE_2D:
  527.    case GL_TEXTURE_2D_ARRAY_EXT:
  528.       maxLevels = ctx->Const.MaxTextureLevels;
  529.       break;
  530.    case GL_TEXTURE_3D:
  531.       maxLevels = ctx->Const.Max3DTextureLevels;
  532.       break;
  533.    case GL_TEXTURE_CUBE_MAP_ARB:
  534.    case GL_TEXTURE_CUBE_MAP_ARRAY:
  535.       maxLevels = ctx->Const.MaxCubeTextureLevels;
  536.       break;
  537.    case GL_TEXTURE_RECTANGLE_NV:
  538.    case GL_TEXTURE_BUFFER:
  539.    case GL_TEXTURE_EXTERNAL_OES:
  540.    case GL_TEXTURE_2D_MULTISAMPLE:
  541.    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
  542.       maxLevels = 1;  /* no mipmapping */
  543.       break;
  544.    default:
  545.       _mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
  546.       return;
  547.    }
  548.  
  549.    ASSERT(maxLevels > 0);
  550.  
  551.    t->_MaxLevel =
  552.       baseLevel + baseImage->MaxNumLevels - 1; /* 'p' in the GL spec */
  553.    t->_MaxLevel = MIN2(t->_MaxLevel, t->MaxLevel);
  554.    t->_MaxLevel = MIN2(t->_MaxLevel, maxLevels - 1); /* 'q' in the GL spec */
  555.  
  556.    /* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
  557.    t->_MaxLambda = (GLfloat) (t->_MaxLevel - baseLevel);
  558.  
  559.    if (t->Immutable) {
  560.       /* This texture object was created with glTexStorage1/2/3D() so we
  561.        * know that all the mipmap levels are the right size and all cube
  562.        * map faces are the same size.
  563.        * We don't need to do any of the additional checks below.
  564.        */
  565.       return;
  566.    }
  567.  
  568.    if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
  569.       /* Make sure that all six cube map level 0 images are the same size.
  570.        * Note:  we know that the image's width==height (we enforce that
  571.        * at glTexImage time) so we only need to test the width here.
  572.        */
  573.       GLuint face;
  574.       assert(baseImage->Width2 == baseImage->Height);
  575.       for (face = 1; face < 6; face++) {
  576.          assert(t->Image[face][baseLevel] == NULL ||
  577.                 t->Image[face][baseLevel]->Width2 ==
  578.                 t->Image[face][baseLevel]->Height2);
  579.          if (t->Image[face][baseLevel] == NULL ||
  580.              t->Image[face][baseLevel]->Width2 != baseImage->Width2) {
  581.             incomplete(t, BASE, "Cube face missing or mismatched size");
  582.             return;
  583.          }
  584.       }
  585.    }
  586.  
  587.    /*
  588.     * Do mipmap consistency checking.
  589.     * Note: we don't care about the current texture sampler state here.
  590.     * To determine texture completeness we'll either look at _BaseComplete
  591.     * or _MipmapComplete depending on the current minification filter mode.
  592.     */
  593.    {
  594.       GLint i;
  595.       const GLint minLevel = baseLevel;
  596.       const GLint maxLevel = t->_MaxLevel;
  597.       const GLuint numFaces = _mesa_num_tex_faces(t->Target);
  598.       GLuint width, height, depth, face;
  599.  
  600.       if (minLevel > maxLevel) {
  601.          incomplete(t, MIPMAP, "minLevel > maxLevel");
  602.          return;
  603.       }
  604.  
  605.       /* Get the base image's dimensions */
  606.       width = baseImage->Width2;
  607.       height = baseImage->Height2;
  608.       depth = baseImage->Depth2;
  609.  
  610.       /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL,
  611.        * MULTISAMPLE and MULTISAMPLE_ARRAY textures
  612.        */
  613.       for (i = baseLevel + 1; i < maxLevels; i++) {
  614.          /* Compute the expected size of image at level[i] */
  615.          if (width > 1) {
  616.             width /= 2;
  617.          }
  618.          if (height > 1 && t->Target != GL_TEXTURE_1D_ARRAY) {
  619.             height /= 2;
  620.          }
  621.          if (depth > 1 && t->Target != GL_TEXTURE_2D_ARRAY && t->Target != GL_TEXTURE_CUBE_MAP_ARRAY) {
  622.             depth /= 2;
  623.          }
  624.  
  625.          /* loop over cube faces (or single face otherwise) */
  626.          for (face = 0; face < numFaces; face++) {
  627.             if (i >= minLevel && i <= maxLevel) {
  628.                const struct gl_texture_image *img = t->Image[face][i];
  629.  
  630.                if (!img) {
  631.                   incomplete(t, MIPMAP, "TexImage[%d] is missing", i);
  632.                   return;
  633.                }
  634.                if (img->TexFormat != baseImage->TexFormat) {
  635.                   incomplete(t, MIPMAP, "Format[i] != Format[baseLevel]");
  636.                   return;
  637.                }
  638.                if (img->Border != baseImage->Border) {
  639.                   incomplete(t, MIPMAP, "Border[i] != Border[baseLevel]");
  640.                   return;
  641.                }
  642.                if (img->Width2 != width) {
  643.                   incomplete(t, MIPMAP, "TexImage[%d] bad width %u", i, img->Width2);
  644.                   return;
  645.                }
  646.                if (img->Height2 != height) {
  647.                   incomplete(t, MIPMAP, "TexImage[%d] bad height %u", i, img->Height2);
  648.                   return;
  649.                }
  650.                if (img->Depth2 != depth) {
  651.                   incomplete(t, MIPMAP, "TexImage[%d] bad depth %u", i, img->Depth2);
  652.                   return;
  653.                }
  654.  
  655.                /* Extra checks for cube textures */
  656.                if (face > 0) {
  657.                   /* check that cube faces are the same size */
  658.                   if (img->Width2 != t->Image[0][i]->Width2 ||
  659.                       img->Height2 != t->Image[0][i]->Height2) {
  660.                      incomplete(t, MIPMAP, "CubeMap Image[n][i] bad size");
  661.                      return;
  662.                   }
  663.                }
  664.             }
  665.          }
  666.          
  667.          if (width == 1 && height == 1 && depth == 1) {
  668.             return;  /* found smallest needed mipmap, all done! */
  669.          }
  670.       }
  671.    }
  672. }
  673.  
  674.  
  675. /**
  676.  * Check if the given cube map texture is "cube complete" as defined in
  677.  * the OpenGL specification.
  678.  */
  679. GLboolean
  680. _mesa_cube_complete(const struct gl_texture_object *texObj)
  681. {
  682.    const GLint baseLevel = texObj->BaseLevel;
  683.    const struct gl_texture_image *img0, *img;
  684.    GLuint face;
  685.  
  686.    if (texObj->Target != GL_TEXTURE_CUBE_MAP)
  687.       return GL_FALSE;
  688.  
  689.    if ((baseLevel < 0) || (baseLevel >= MAX_TEXTURE_LEVELS))
  690.       return GL_FALSE;
  691.  
  692.    /* check first face */
  693.    img0 = texObj->Image[0][baseLevel];
  694.    if (!img0 ||
  695.        img0->Width < 1 ||
  696.        img0->Width != img0->Height)
  697.       return GL_FALSE;
  698.  
  699.    /* check remaining faces vs. first face */
  700.    for (face = 1; face < 6; face++) {
  701.       img = texObj->Image[face][baseLevel];
  702.       if (!img ||
  703.           img->Width != img0->Width ||
  704.           img->Height != img0->Height ||
  705.           img->TexFormat != img0->TexFormat)
  706.          return GL_FALSE;
  707.    }
  708.  
  709.    return GL_TRUE;
  710. }
  711.  
  712.  
  713. /**
  714.  * Mark a texture object dirty.  It forces the object to be incomplete
  715.  * and optionally forces the context to re-validate its state.
  716.  *
  717.  * \param ctx GL context.
  718.  * \param texObj texture object.
  719.  * \param invalidate_state also invalidate context state.
  720.  */
  721. void
  722. _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj,
  723.                    GLboolean invalidate_state)
  724. {
  725.    texObj->_BaseComplete = GL_FALSE;
  726.    texObj->_MipmapComplete = GL_FALSE;
  727.    if (invalidate_state)
  728.       ctx->NewState |= _NEW_TEXTURE;
  729. }
  730.  
  731.  
  732. /**
  733.  * Return pointer to a default/fallback texture of the given type/target.
  734.  * The texture is an RGBA texture with all texels = (0,0,0,1).
  735.  * That's the value a GLSL sampler should get when sampling from an
  736.  * incomplete texture.
  737.  */
  738. struct gl_texture_object *
  739. _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
  740. {
  741.    if (!ctx->Shared->FallbackTex[tex]) {
  742.       /* create fallback texture now */
  743.       const GLsizei width = 1, height = 1, depth = 1;
  744.       GLubyte texel[4];
  745.       struct gl_texture_object *texObj;
  746.       struct gl_texture_image *texImage;
  747.       gl_format texFormat;
  748.       GLuint dims, face, numFaces = 1;
  749.       GLenum target;
  750.  
  751.       texel[0] =
  752.       texel[1] =
  753.       texel[2] = 0x0;
  754.       texel[3] = 0xff;
  755.  
  756.       switch (tex) {
  757.       case TEXTURE_2D_ARRAY_INDEX:
  758.          dims = 3;
  759.          target = GL_TEXTURE_2D_ARRAY;
  760.          break;
  761.       case TEXTURE_1D_ARRAY_INDEX:
  762.          dims = 2;
  763.          target = GL_TEXTURE_1D_ARRAY;
  764.          break;
  765.       case TEXTURE_CUBE_INDEX:
  766.          dims = 2;
  767.          target = GL_TEXTURE_CUBE_MAP;
  768.          numFaces = 6;
  769.          break;
  770.       case TEXTURE_3D_INDEX:
  771.          dims = 3;
  772.          target = GL_TEXTURE_3D;
  773.          break;
  774.       case TEXTURE_RECT_INDEX:
  775.          dims = 2;
  776.          target = GL_TEXTURE_RECTANGLE;
  777.          break;
  778.       case TEXTURE_2D_INDEX:
  779.          dims = 2;
  780.          target = GL_TEXTURE_2D;
  781.          break;
  782.       case TEXTURE_1D_INDEX:
  783.          dims = 1;
  784.          target = GL_TEXTURE_1D;
  785.          break;
  786.       case TEXTURE_BUFFER_INDEX:
  787.          dims = 0;
  788.          target = GL_TEXTURE_BUFFER;
  789.          break;
  790.       case TEXTURE_CUBE_ARRAY_INDEX:
  791.          dims = 3;
  792.          target = GL_TEXTURE_CUBE_MAP_ARRAY;
  793.          break;
  794.       case TEXTURE_EXTERNAL_INDEX:
  795.          dims = 2;
  796.          target = GL_TEXTURE_EXTERNAL_OES;
  797.          break;
  798.       case TEXTURE_2D_MULTISAMPLE_INDEX:
  799.          dims = 2;
  800.          target = GL_TEXTURE_2D_MULTISAMPLE;
  801.          break;
  802.       case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX:
  803.          dims = 3;
  804.          target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
  805.          break;
  806.       default:
  807.          /* no-op */
  808.          return NULL;
  809.       }
  810.  
  811.       /* create texture object */
  812.       texObj = ctx->Driver.NewTextureObject(ctx, 0, target);
  813.       if (!texObj)
  814.          return NULL;
  815.  
  816.       assert(texObj->RefCount == 1);
  817.       texObj->Sampler.MinFilter = GL_NEAREST;
  818.       texObj->Sampler.MagFilter = GL_NEAREST;
  819.  
  820.       texFormat = ctx->Driver.ChooseTextureFormat(ctx, target,
  821.                                                   GL_RGBA, GL_RGBA,
  822.                                                   GL_UNSIGNED_BYTE);
  823.  
  824.       /* need a loop here just for cube maps */
  825.       for (face = 0; face < numFaces; face++) {
  826.          GLenum faceTarget;
  827.  
  828.          if (target == GL_TEXTURE_CUBE_MAP)
  829.             faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
  830.          else
  831.             faceTarget = target;
  832.  
  833.          /* initialize level[0] texture image */
  834.          texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, 0);
  835.  
  836.          _mesa_init_teximage_fields(ctx, texImage,
  837.                                     width,
  838.                                     (dims > 1) ? height : 1,
  839.                                     (dims > 2) ? depth : 1,
  840.                                     0, /* border */
  841.                                     GL_RGBA, texFormat);
  842.  
  843.          ctx->Driver.TexImage(ctx, dims, texImage,
  844.                               GL_RGBA, GL_UNSIGNED_BYTE, texel,
  845.                               &ctx->DefaultPacking);
  846.       }
  847.  
  848.       _mesa_test_texobj_completeness(ctx, texObj);
  849.       assert(texObj->_BaseComplete);
  850.       assert(texObj->_MipmapComplete);
  851.  
  852.       ctx->Shared->FallbackTex[tex] = texObj;
  853.    }
  854.    return ctx->Shared->FallbackTex[tex];
  855. }
  856.  
  857.  
  858. /**
  859.  * Compute the size of the given texture object, in bytes.
  860.  */
  861. static GLuint
  862. texture_size(const struct gl_texture_object *texObj)
  863. {
  864.    const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
  865.    GLuint face, level, size = 0;
  866.  
  867.    for (face = 0; face < numFaces; face++) {
  868.       for (level = 0; level < MAX_TEXTURE_LEVELS; level++) {
  869.          const struct gl_texture_image *img = texObj->Image[face][level];
  870.          if (img) {
  871.             GLuint sz = _mesa_format_image_size(img->TexFormat, img->Width,
  872.                                                 img->Height, img->Depth);
  873.             size += sz;
  874.          }
  875.       }
  876.    }
  877.  
  878.    return size;
  879. }
  880.  
  881.  
  882. /**
  883.  * Callback called from _mesa_HashWalk()
  884.  */
  885. static void
  886. count_tex_size(GLuint key, void *data, void *userData)
  887. {
  888.    const struct gl_texture_object *texObj =
  889.       (const struct gl_texture_object *) data;
  890.    GLuint *total = (GLuint *) userData;
  891.  
  892.    *total = *total + texture_size(texObj);
  893. }
  894.  
  895.  
  896. /**
  897.  * Compute total size (in bytes) of all textures for the given context.
  898.  * For debugging purposes.
  899.  */
  900. GLuint
  901. _mesa_total_texture_memory(struct gl_context *ctx)
  902. {
  903.    GLuint tgt, total = 0;
  904.  
  905.    _mesa_HashWalk(ctx->Shared->TexObjects, count_tex_size, &total);
  906.  
  907.    /* plus, the default texture objects */
  908.    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
  909.       total += texture_size(ctx->Shared->DefaultTex[tgt]);
  910.    }
  911.  
  912.    return total;
  913. }
  914.  
  915. static struct gl_texture_object *
  916. invalidate_tex_image_error_check(struct gl_context *ctx, GLuint texture,
  917.                                  GLint level, const char *name)
  918. {
  919.    /* The GL_ARB_invalidate_subdata spec says:
  920.     *
  921.     *     "If <texture> is zero or is not the name of a texture, the error
  922.     *     INVALID_VALUE is generated."
  923.     *
  924.     * This performs the error check in a different order than listed in the
  925.     * spec.  We have to get the texture object before we can validate the
  926.     * other parameters against values in the texture object.
  927.     */
  928.    struct gl_texture_object *const t = _mesa_lookup_texture(ctx, texture);
  929.    if (texture == 0 || t == NULL) {
  930.       _mesa_error(ctx, GL_INVALID_VALUE, "%s(texture)", name);
  931.       return NULL;
  932.    }
  933.  
  934.    /* The GL_ARB_invalidate_subdata spec says:
  935.     *
  936.     *     "If <level> is less than zero or greater than the base 2 logarithm
  937.     *     of the maximum texture width, height, or depth, the error
  938.     *     INVALID_VALUE is generated."
  939.     */
  940.    if (level < 0 || level > t->MaxLevel) {
  941.       _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
  942.       return NULL;
  943.    }
  944.  
  945.    /* The GL_ARB_invalidate_subdata spec says:
  946.     *
  947.     *     "If the target of <texture> is TEXTURE_RECTANGLE, TEXTURE_BUFFER,
  948.     *     TEXTURE_2D_MULTISAMPLE, or TEXTURE_2D_MULTISAMPLE_ARRAY, and <level>
  949.     *     is not zero, the error INVALID_VALUE is generated."
  950.     */
  951.    if (level != 0) {
  952.       switch (t->Target) {
  953.       case GL_TEXTURE_RECTANGLE:
  954.       case GL_TEXTURE_BUFFER:
  955.       case GL_TEXTURE_2D_MULTISAMPLE:
  956.       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
  957.          _mesa_error(ctx, GL_INVALID_VALUE, "%s(level)", name);
  958.          return NULL;
  959.  
  960.       default:
  961.          break;
  962.       }
  963.    }
  964.  
  965.    return t;
  966. }
  967.  
  968. /*@}*/
  969.  
  970.  
  971. /***********************************************************************/
  972. /** \name API functions */
  973. /*@{*/
  974.  
  975.  
  976. /**
  977.  * Generate texture names.
  978.  *
  979.  * \param n number of texture names to be generated.
  980.  * \param textures an array in which will hold the generated texture names.
  981.  *
  982.  * \sa glGenTextures().
  983.  *
  984.  * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture
  985.  * IDs which are stored in \p textures.  Corresponding empty texture
  986.  * objects are also generated.
  987.  */
  988. void GLAPIENTRY
  989. _mesa_GenTextures( GLsizei n, GLuint *textures )
  990. {
  991.    GET_CURRENT_CONTEXT(ctx);
  992.    GLuint first;
  993.    GLint i;
  994.  
  995.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  996.       _mesa_debug(ctx, "glGenTextures %d\n", n);
  997.  
  998.    if (n < 0) {
  999.       _mesa_error( ctx, GL_INVALID_VALUE, "glGenTextures" );
  1000.       return;
  1001.    }
  1002.  
  1003.    if (!textures)
  1004.       return;
  1005.  
  1006.    /*
  1007.     * This must be atomic (generation and allocation of texture IDs)
  1008.     */
  1009.    _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
  1010.  
  1011.    first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n);
  1012.  
  1013.    /* Allocate new, empty texture objects */
  1014.    for (i = 0; i < n; i++) {
  1015.       struct gl_texture_object *texObj;
  1016.       GLuint name = first + i;
  1017.       GLenum target = 0;
  1018.       texObj = ctx->Driver.NewTextureObject(ctx, name, target);
  1019.       if (!texObj) {
  1020.          _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
  1021.          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures");
  1022.          return;
  1023.       }
  1024.  
  1025.       /* insert into hash table */
  1026.       _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj);
  1027.  
  1028.       textures[i] = name;
  1029.    }
  1030.  
  1031.    _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
  1032. }
  1033.  
  1034.  
  1035. /**
  1036.  * Check if the given texture object is bound to the current draw or
  1037.  * read framebuffer.  If so, Unbind it.
  1038.  */
  1039. static void
  1040. unbind_texobj_from_fbo(struct gl_context *ctx,
  1041.                        struct gl_texture_object *texObj)
  1042. {
  1043.    bool progress = false;
  1044.  
  1045.    /* Section 4.4.2 (Attaching Images to Framebuffer Objects), subsection
  1046.     * "Attaching Texture Images to a Framebuffer," of the OpenGL 3.1 spec
  1047.     * says:
  1048.     *
  1049.     *     "If a texture object is deleted while its image is attached to one
  1050.     *     or more attachment points in the currently bound framebuffer, then
  1051.     *     it is as if FramebufferTexture* had been called, with a texture of
  1052.     *     zero, for each attachment point to which this image was attached in
  1053.     *     the currently bound framebuffer. In other words, this texture image
  1054.     *     is first detached from all attachment points in the currently bound
  1055.     *     framebuffer. Note that the texture image is specifically not
  1056.     *     detached from any other framebuffer objects. Detaching the texture
  1057.     *     image from any other framebuffer objects is the responsibility of
  1058.     *     the application."
  1059.     */
  1060.    if (_mesa_is_user_fbo(ctx->DrawBuffer)) {
  1061.       progress = _mesa_detach_renderbuffer(ctx, ctx->DrawBuffer, texObj);
  1062.    }
  1063.    if (_mesa_is_user_fbo(ctx->ReadBuffer)
  1064.        && ctx->ReadBuffer != ctx->DrawBuffer) {
  1065.       progress = _mesa_detach_renderbuffer(ctx, ctx->ReadBuffer, texObj)
  1066.          || progress;
  1067.    }
  1068.  
  1069.    if (progress)
  1070.       /* Vertices are already flushed by _mesa_DeleteTextures */
  1071.       ctx->NewState |= _NEW_BUFFERS;
  1072. }
  1073.  
  1074.  
  1075. /**
  1076.  * Check if the given texture object is bound to any texture image units and
  1077.  * unbind it if so (revert to default textures).
  1078.  */
  1079. static void
  1080. unbind_texobj_from_texunits(struct gl_context *ctx,
  1081.                             struct gl_texture_object *texObj)
  1082. {
  1083.    GLuint u, tex;
  1084.  
  1085.    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
  1086.       struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
  1087.       for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
  1088.          if (texObj == unit->CurrentTex[tex]) {
  1089.             _mesa_reference_texobj(&unit->CurrentTex[tex],
  1090.                                    ctx->Shared->DefaultTex[tex]);
  1091.             ASSERT(unit->CurrentTex[tex]);
  1092.             break;
  1093.          }
  1094.       }
  1095.    }
  1096. }
  1097.  
  1098.  
  1099. /**
  1100.  * Delete named textures.
  1101.  *
  1102.  * \param n number of textures to be deleted.
  1103.  * \param textures array of texture IDs to be deleted.
  1104.  *
  1105.  * \sa glDeleteTextures().
  1106.  *
  1107.  * If we're about to delete a texture that's currently bound to any
  1108.  * texture unit, unbind the texture first.  Decrement the reference
  1109.  * count on the texture object and delete it if it's zero.
  1110.  * Recall that texture objects can be shared among several rendering
  1111.  * contexts.
  1112.  */
  1113. void GLAPIENTRY
  1114. _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
  1115. {
  1116.    GET_CURRENT_CONTEXT(ctx);
  1117.    GLint i;
  1118.  
  1119.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  1120.       _mesa_debug(ctx, "glDeleteTextures %d\n", n);
  1121.  
  1122.    FLUSH_VERTICES(ctx, 0); /* too complex */
  1123.  
  1124.    if (!textures)
  1125.       return;
  1126.  
  1127.    for (i = 0; i < n; i++) {
  1128.       if (textures[i] > 0) {
  1129.          struct gl_texture_object *delObj
  1130.             = _mesa_lookup_texture(ctx, textures[i]);
  1131.  
  1132.          if (delObj) {
  1133.             _mesa_lock_texture(ctx, delObj);
  1134.  
  1135.             /* Check if texture is bound to any framebuffer objects.
  1136.              * If so, unbind.
  1137.              * See section 4.4.2.3 of GL_EXT_framebuffer_object.
  1138.              */
  1139.             unbind_texobj_from_fbo(ctx, delObj);
  1140.  
  1141.             /* Check if this texture is currently bound to any texture units.
  1142.              * If so, unbind it.
  1143.              */
  1144.             unbind_texobj_from_texunits(ctx, delObj);
  1145.  
  1146.             _mesa_unlock_texture(ctx, delObj);
  1147.  
  1148.             ctx->NewState |= _NEW_TEXTURE;
  1149.  
  1150.             /* The texture _name_ is now free for re-use.
  1151.              * Remove it from the hash table now.
  1152.              */
  1153.             _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
  1154.             _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
  1155.             _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
  1156.  
  1157.             /* Unreference the texobj.  If refcount hits zero, the texture
  1158.              * will be deleted.
  1159.              */
  1160.             _mesa_reference_texobj(&delObj, NULL);
  1161.          }
  1162.       }
  1163.    }
  1164. }
  1165.  
  1166.  
  1167. /**
  1168.  * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
  1169.  * into the corresponding Mesa texture target index.
  1170.  * Note that proxy targets are not valid here.
  1171.  * \return TEXTURE_x_INDEX or -1 if target is invalid
  1172.  */
  1173. static GLint
  1174. target_enum_to_index(struct gl_context *ctx, GLenum target)
  1175. {
  1176.    switch (target) {
  1177.    case GL_TEXTURE_1D:
  1178.       return _mesa_is_desktop_gl(ctx) ? TEXTURE_1D_INDEX : -1;
  1179.    case GL_TEXTURE_2D:
  1180.       return TEXTURE_2D_INDEX;
  1181.    case GL_TEXTURE_3D:
  1182.       return TEXTURE_3D_INDEX;
  1183.    case GL_TEXTURE_CUBE_MAP_ARB:
  1184.       return ctx->Extensions.ARB_texture_cube_map
  1185.          ? TEXTURE_CUBE_INDEX : -1;
  1186.    case GL_TEXTURE_RECTANGLE_NV:
  1187.       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle
  1188.          ? TEXTURE_RECT_INDEX : -1;
  1189.    case GL_TEXTURE_1D_ARRAY_EXT:
  1190.       return _mesa_is_desktop_gl(ctx)
  1191.          && (ctx->Extensions.EXT_texture_array
  1192.              || ctx->Extensions.MESA_texture_array)
  1193.          ? TEXTURE_1D_ARRAY_INDEX : -1;
  1194.    case GL_TEXTURE_2D_ARRAY_EXT:
  1195.       return (_mesa_is_desktop_gl(ctx)
  1196.               && (ctx->Extensions.EXT_texture_array
  1197.                   || ctx->Extensions.MESA_texture_array))
  1198.          || _mesa_is_gles3(ctx)
  1199.          ? TEXTURE_2D_ARRAY_INDEX : -1;
  1200.    case GL_TEXTURE_BUFFER_ARB:
  1201.       return ctx->API == API_OPENGL_CORE &&
  1202.              ctx->Extensions.ARB_texture_buffer_object ?
  1203.              TEXTURE_BUFFER_INDEX : -1;
  1204.    case GL_TEXTURE_EXTERNAL_OES:
  1205.       return _mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external
  1206.          ? TEXTURE_EXTERNAL_INDEX : -1;
  1207.    case GL_TEXTURE_CUBE_MAP_ARRAY:
  1208.       return TEXTURE_CUBE_ARRAY_INDEX;
  1209.    case GL_TEXTURE_2D_MULTISAMPLE:
  1210.       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
  1211.          ? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
  1212.    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
  1213.       return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
  1214.          ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1;
  1215.    default:
  1216.       return -1;
  1217.    }
  1218. }
  1219.  
  1220.  
  1221. /**
  1222.  * Bind a named texture to a texturing target.
  1223.  *
  1224.  * \param target texture target.
  1225.  * \param texName texture name.
  1226.  *
  1227.  * \sa glBindTexture().
  1228.  *
  1229.  * Determines the old texture object bound and returns immediately if rebinding
  1230.  * the same texture.  Get the current texture which is either a default texture
  1231.  * if name is null, a named texture from the hash, or a new texture if the
  1232.  * given texture name is new. Increments its reference count, binds it, and
  1233.  * calls dd_function_table::BindTexture. Decrements the old texture reference
  1234.  * count and deletes it if it reaches zero.
  1235.  */
  1236. void GLAPIENTRY
  1237. _mesa_BindTexture( GLenum target, GLuint texName )
  1238. {
  1239.    GET_CURRENT_CONTEXT(ctx);
  1240.    struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
  1241.    struct gl_texture_object *newTexObj = NULL;
  1242.    GLint targetIndex;
  1243.  
  1244.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  1245.       _mesa_debug(ctx, "glBindTexture %s %d\n",
  1246.                   _mesa_lookup_enum_by_nr(target), (GLint) texName);
  1247.  
  1248.    targetIndex = target_enum_to_index(ctx, target);
  1249.    if (targetIndex < 0) {
  1250.       _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
  1251.       return;
  1252.    }
  1253.    assert(targetIndex < NUM_TEXTURE_TARGETS);
  1254.  
  1255.    /*
  1256.     * Get pointer to new texture object (newTexObj)
  1257.     */
  1258.    if (texName == 0) {
  1259.       /* Use a default texture object */
  1260.       newTexObj = ctx->Shared->DefaultTex[targetIndex];
  1261.    }
  1262.    else {
  1263.       /* non-default texture object */
  1264.       newTexObj = _mesa_lookup_texture(ctx, texName);
  1265.       if (newTexObj) {
  1266.          /* error checking */
  1267.          if (newTexObj->Target != 0 && newTexObj->Target != target) {
  1268.             /* the named texture object's target doesn't match the given target */
  1269.             _mesa_error( ctx, GL_INVALID_OPERATION,
  1270.                          "glBindTexture(target mismatch)" );
  1271.             return;
  1272.          }
  1273.          if (newTexObj->Target == 0) {
  1274.             finish_texture_init(ctx, target, newTexObj);
  1275.          }
  1276.       }
  1277.       else {
  1278.          if (ctx->API == API_OPENGL_CORE) {
  1279.             _mesa_error(ctx, GL_INVALID_OPERATION, "glBindTexture(non-gen name)");
  1280.             return;
  1281.          }
  1282.  
  1283.          /* if this is a new texture id, allocate a texture object now */
  1284.          newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target);
  1285.          if (!newTexObj) {
  1286.             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
  1287.             return;
  1288.          }
  1289.  
  1290.          /* and insert it into hash table */
  1291.          _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
  1292.          _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj);
  1293.          _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
  1294.       }
  1295.       newTexObj->Target = target;
  1296.    }
  1297.  
  1298.    assert(valid_texture_object(newTexObj));
  1299.  
  1300.    /* Check if this texture is only used by this context and is already bound.
  1301.     * If so, just return.
  1302.     */
  1303.    {
  1304.       GLboolean early_out;
  1305.       _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
  1306.       early_out = ((ctx->Shared->RefCount == 1)
  1307.                    && (newTexObj == texUnit->CurrentTex[targetIndex]));
  1308.       _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
  1309.       if (early_out) {
  1310.          return;
  1311.       }
  1312.    }
  1313.  
  1314.    /* flush before changing binding */
  1315.    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
  1316.  
  1317.    /* Do the actual binding.  The refcount on the previously bound
  1318.     * texture object will be decremented.  It'll be deleted if the
  1319.     * count hits zero.
  1320.     */
  1321.    _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj);
  1322.    ASSERT(texUnit->CurrentTex[targetIndex]);
  1323.  
  1324.    /* Pass BindTexture call to device driver */
  1325.    if (ctx->Driver.BindTexture)
  1326.       ctx->Driver.BindTexture(ctx, target, newTexObj);
  1327. }
  1328.  
  1329.  
  1330. /**
  1331.  * Set texture priorities.
  1332.  *
  1333.  * \param n number of textures.
  1334.  * \param texName texture names.
  1335.  * \param priorities corresponding texture priorities.
  1336.  *
  1337.  * \sa glPrioritizeTextures().
  1338.  *
  1339.  * Looks up each texture in the hash, clamps the corresponding priority between
  1340.  * 0.0 and 1.0, and calls dd_function_table::PrioritizeTexture.
  1341.  */
  1342. void GLAPIENTRY
  1343. _mesa_PrioritizeTextures( GLsizei n, const GLuint *texName,
  1344.                           const GLclampf *priorities )
  1345. {
  1346.    GET_CURRENT_CONTEXT(ctx);
  1347.    GLint i;
  1348.  
  1349.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  1350.       _mesa_debug(ctx, "glPrioritizeTextures %d\n", n);
  1351.  
  1352.    FLUSH_VERTICES(ctx, 0);
  1353.  
  1354.    if (n < 0) {
  1355.       _mesa_error( ctx, GL_INVALID_VALUE, "glPrioritizeTextures" );
  1356.       return;
  1357.    }
  1358.  
  1359.    if (!priorities)
  1360.       return;
  1361.  
  1362.    for (i = 0; i < n; i++) {
  1363.       if (texName[i] > 0) {
  1364.          struct gl_texture_object *t = _mesa_lookup_texture(ctx, texName[i]);
  1365.          if (t) {
  1366.             t->Priority = CLAMP( priorities[i], 0.0F, 1.0F );
  1367.          }
  1368.       }
  1369.    }
  1370.  
  1371.    ctx->NewState |= _NEW_TEXTURE;
  1372. }
  1373.  
  1374.  
  1375.  
  1376. /**
  1377.  * See if textures are loaded in texture memory.
  1378.  *
  1379.  * \param n number of textures to query.
  1380.  * \param texName array with the texture names.
  1381.  * \param residences array which will hold the residence status.
  1382.  *
  1383.  * \return GL_TRUE if all textures are resident and \p residences is left unchanged,
  1384.  *
  1385.  * Note: we assume all textures are always resident
  1386.  */
  1387. GLboolean GLAPIENTRY
  1388. _mesa_AreTexturesResident(GLsizei n, const GLuint *texName,
  1389.                           GLboolean *residences)
  1390. {
  1391.    GET_CURRENT_CONTEXT(ctx);
  1392.    GLboolean allResident = GL_TRUE;
  1393.    GLint i;
  1394.    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
  1395.  
  1396.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  1397.       _mesa_debug(ctx, "glAreTexturesResident %d\n", n);
  1398.  
  1399.    if (n < 0) {
  1400.       _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident(n)");
  1401.       return GL_FALSE;
  1402.    }
  1403.  
  1404.    if (!texName || !residences)
  1405.       return GL_FALSE;
  1406.  
  1407.    /* We only do error checking on the texture names */
  1408.    for (i = 0; i < n; i++) {
  1409.       struct gl_texture_object *t;
  1410.       if (texName[i] == 0) {
  1411.          _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
  1412.          return GL_FALSE;
  1413.       }
  1414.       t = _mesa_lookup_texture(ctx, texName[i]);
  1415.       if (!t) {
  1416.          _mesa_error(ctx, GL_INVALID_VALUE, "glAreTexturesResident");
  1417.          return GL_FALSE;
  1418.       }
  1419.    }
  1420.    
  1421.    return allResident;
  1422. }
  1423.  
  1424.  
  1425. /**
  1426.  * See if a name corresponds to a texture.
  1427.  *
  1428.  * \param texture texture name.
  1429.  *
  1430.  * \return GL_TRUE if texture name corresponds to a texture, or GL_FALSE
  1431.  * otherwise.
  1432.  *
  1433.  * \sa glIsTexture().
  1434.  *
  1435.  * Calls _mesa_HashLookup().
  1436.  */
  1437. GLboolean GLAPIENTRY
  1438. _mesa_IsTexture( GLuint texture )
  1439. {
  1440.    struct gl_texture_object *t;
  1441.    GET_CURRENT_CONTEXT(ctx);
  1442.    ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
  1443.  
  1444.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  1445.       _mesa_debug(ctx, "glIsTexture %d\n", texture);
  1446.  
  1447.    if (!texture)
  1448.       return GL_FALSE;
  1449.  
  1450.    t = _mesa_lookup_texture(ctx, texture);
  1451.  
  1452.    /* IsTexture is true only after object has been bound once. */
  1453.    return t && t->Target;
  1454. }
  1455.  
  1456.  
  1457. /**
  1458.  * Simplest implementation of texture locking: grab the shared tex
  1459.  * mutex.  Examine the shared context state timestamp and if there has
  1460.  * been a change, set the appropriate bits in ctx->NewState.
  1461.  *
  1462.  * This is used to deal with synchronizing things when a texture object
  1463.  * is used/modified by different contexts (or threads) which are sharing
  1464.  * the texture.
  1465.  *
  1466.  * See also _mesa_lock/unlock_texture() in teximage.h
  1467.  */
  1468. void
  1469. _mesa_lock_context_textures( struct gl_context *ctx )
  1470. {
  1471.    _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
  1472.  
  1473.    if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) {
  1474.       ctx->NewState |= _NEW_TEXTURE;
  1475.       ctx->TextureStateTimestamp = ctx->Shared->TextureStateStamp;
  1476.    }
  1477. }
  1478.  
  1479.  
  1480. void
  1481. _mesa_unlock_context_textures( struct gl_context *ctx )
  1482. {
  1483.    assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp);
  1484.    _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
  1485. }
  1486.  
  1487. void GLAPIENTRY
  1488. _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
  1489.                             GLint yoffset, GLint zoffset, GLsizei width,
  1490.                             GLsizei height, GLsizei depth)
  1491. {
  1492.    struct gl_texture_object *t;
  1493.    struct gl_texture_image *image;
  1494.    GET_CURRENT_CONTEXT(ctx);
  1495.  
  1496.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  1497.       _mesa_debug(ctx, "glInvalidateTexSubImage %d\n", texture);
  1498.  
  1499.    t = invalidate_tex_image_error_check(ctx, texture, level,
  1500.                                         "glInvalidateTexSubImage");
  1501.  
  1502.    /* The GL_ARB_invalidate_subdata spec says:
  1503.     *
  1504.     *     "...the specified subregion must be between -<b> and <dim>+<b> where
  1505.     *     <dim> is the size of the dimension of the texture image, and <b> is
  1506.     *     the size of the border of that texture image, otherwise
  1507.     *     INVALID_VALUE is generated (border is not applied to dimensions that
  1508.     *     don't exist in a given texture target)."
  1509.     */
  1510.    image = t->Image[0][level];
  1511.    if (image) {
  1512.       int xBorder;
  1513.       int yBorder;
  1514.       int zBorder;
  1515.       int imageWidth;
  1516.       int imageHeight;
  1517.       int imageDepth;
  1518.  
  1519.       /* The GL_ARB_invalidate_subdata spec says:
  1520.        *
  1521.        *     "For texture targets that don't have certain dimensions, this
  1522.        *     command treats those dimensions as having a size of 1. For
  1523.        *     example, to invalidate a portion of a two-dimensional texture,
  1524.        *     the application would use <zoffset> equal to zero and <depth>
  1525.        *     equal to one."
  1526.        */
  1527.       switch (t->Target) {
  1528.       case GL_TEXTURE_BUFFER:
  1529.          xBorder = 0;
  1530.          yBorder = 0;
  1531.          zBorder = 0;
  1532.          imageWidth = 1;
  1533.          imageHeight = 1;
  1534.          imageDepth = 1;
  1535.          break;
  1536.       case GL_TEXTURE_1D:
  1537.          xBorder = image->Border;
  1538.          yBorder = 0;
  1539.          zBorder = 0;
  1540.          imageWidth = image->Width;
  1541.          imageHeight = 1;
  1542.          imageDepth = 1;
  1543.          break;
  1544.       case GL_TEXTURE_1D_ARRAY:
  1545.          xBorder = image->Border;
  1546.          yBorder = 0;
  1547.          zBorder = 0;
  1548.          imageWidth = image->Width;
  1549.          imageHeight = image->Height;
  1550.          imageDepth = 1;
  1551.          break;
  1552.       case GL_TEXTURE_2D:
  1553.       case GL_TEXTURE_CUBE_MAP:
  1554.       case GL_TEXTURE_RECTANGLE:
  1555.       case GL_TEXTURE_2D_MULTISAMPLE:
  1556.          xBorder = image->Border;
  1557.          yBorder = image->Border;
  1558.          zBorder = 0;
  1559.          imageWidth = image->Width;
  1560.          imageHeight = image->Height;
  1561.          imageDepth = 1;
  1562.          break;
  1563.       case GL_TEXTURE_2D_ARRAY:
  1564.       case GL_TEXTURE_CUBE_MAP_ARRAY:
  1565.       case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
  1566.          xBorder = image->Border;
  1567.          yBorder = image->Border;
  1568.          zBorder = 0;
  1569.          imageWidth = image->Width;
  1570.          imageHeight = image->Height;
  1571.          imageDepth = image->Depth;
  1572.          break;
  1573.       case GL_TEXTURE_3D:
  1574.          xBorder = image->Border;
  1575.          yBorder = image->Border;
  1576.          zBorder = image->Border;
  1577.          imageWidth = image->Width;
  1578.          imageHeight = image->Height;
  1579.          imageDepth = image->Depth;
  1580.          break;
  1581.       default:
  1582.          assert(!"Should not get here.");
  1583.          xBorder = 0;
  1584.          yBorder = 0;
  1585.          zBorder = 0;
  1586.          imageWidth = 0;
  1587.          imageHeight = 0;
  1588.          imageDepth = 0;
  1589.          break;
  1590.       }
  1591.  
  1592.       if (xoffset < -xBorder) {
  1593.          _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(xoffset)");
  1594.          return;
  1595.       }
  1596.  
  1597.       if (xoffset + width > imageWidth + xBorder) {
  1598.          _mesa_error(ctx, GL_INVALID_VALUE,
  1599.                      "glInvalidateSubTexImage(xoffset+width)");
  1600.          return;
  1601.       }
  1602.  
  1603.       if (yoffset < -yBorder) {
  1604.          _mesa_error(ctx, GL_INVALID_VALUE, "glInvalidateSubTexImage(yoffset)");
  1605.          return;
  1606.       }
  1607.  
  1608.       if (yoffset + height > imageHeight + yBorder) {
  1609.          _mesa_error(ctx, GL_INVALID_VALUE,
  1610.                      "glInvalidateSubTexImage(yoffset+height)");
  1611.          return;
  1612.       }
  1613.  
  1614.       if (zoffset < -zBorder) {
  1615.          _mesa_error(ctx, GL_INVALID_VALUE,
  1616.                      "glInvalidateSubTexImage(zoffset)");
  1617.          return;
  1618.       }
  1619.  
  1620.       if (zoffset + depth  > imageDepth + zBorder) {
  1621.          _mesa_error(ctx, GL_INVALID_VALUE,
  1622.                      "glInvalidateSubTexImage(zoffset+depth)");
  1623.          return;
  1624.       }
  1625.    }
  1626.  
  1627.    /* We don't actually do anything for this yet.  Just return after
  1628.     * validating the parameters and generating the required errors.
  1629.     */
  1630.    return;
  1631. }
  1632.  
  1633. void GLAPIENTRY
  1634. _mesa_InvalidateTexImage(GLuint texture, GLint level)
  1635. {
  1636.    GET_CURRENT_CONTEXT(ctx);
  1637.  
  1638.    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
  1639.       _mesa_debug(ctx, "glInvalidateTexImage(%d, %d)\n", texture, level);
  1640.  
  1641.    invalidate_tex_image_error_check(ctx, texture, level,
  1642.                                     "glInvalidateTexImage");
  1643.  
  1644.    /* We don't actually do anything for this yet.  Just return after
  1645.     * validating the parameters and generating the required errors.
  1646.     */
  1647.    return;
  1648. }
  1649.  
  1650. /*@}*/
  1651.