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