Home | History | Annotate | Download | only in main
      1 /*
      2  * Mesa 3-D graphics library
      3  * Version:  7.5
      4  *
      5  * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     11  * and/or sell copies of the Software, and to permit persons to whom the
     12  * Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included
     15  * in all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     23  */
     24 
     25 /**
     26  * \file texstate.c
     27  *
     28  * Texture state handling.
     29  */
     30 
     31 #include "glheader.h"
     32 #include "mfeatures.h"
     33 #include "bufferobj.h"
     34 #include "colormac.h"
     35 #include "colortab.h"
     36 #include "context.h"
     37 #include "enums.h"
     38 #include "macros.h"
     39 #include "texobj.h"
     40 #include "teximage.h"
     41 #include "texstate.h"
     42 #include "mtypes.h"
     43 
     44 
     45 
     46 /**
     47  * Default texture combine environment state.  This is used to initialize
     48  * a context's texture units and as the basis for converting "classic"
     49  * texture environmnets to ARB_texture_env_combine style values.
     50  */
     51 static const struct gl_tex_env_combine_state default_combine_state = {
     52    GL_MODULATE, GL_MODULATE,
     53    { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
     54    { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
     55    { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_ALPHA },
     56    { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
     57    0, 0,
     58    2, 2
     59 };
     60 
     61 
     62 
     63 /**
     64  * Used by glXCopyContext to copy texture state from one context to another.
     65  */
     66 void
     67 _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
     68 {
     69    GLuint u, tex;
     70 
     71    ASSERT(src);
     72    ASSERT(dst);
     73 
     74    dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
     75    dst->Texture._GenFlags = src->Texture._GenFlags;
     76    dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
     77    dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
     78 
     79    /* per-unit state */
     80    for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
     81       dst->Texture.Unit[u].Enabled = src->Texture.Unit[u].Enabled;
     82       dst->Texture.Unit[u].EnvMode = src->Texture.Unit[u].EnvMode;
     83       COPY_4V(dst->Texture.Unit[u].EnvColor, src->Texture.Unit[u].EnvColor);
     84       dst->Texture.Unit[u].TexGenEnabled = src->Texture.Unit[u].TexGenEnabled;
     85       dst->Texture.Unit[u].GenS = src->Texture.Unit[u].GenS;
     86       dst->Texture.Unit[u].GenT = src->Texture.Unit[u].GenT;
     87       dst->Texture.Unit[u].GenR = src->Texture.Unit[u].GenR;
     88       dst->Texture.Unit[u].GenQ = src->Texture.Unit[u].GenQ;
     89       dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
     90 
     91       /* GL_EXT_texture_env_combine */
     92       dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine;
     93 
     94       /* GL_ATI_envmap_bumpmap - need this? */
     95       dst->Texture.Unit[u].BumpTarget = src->Texture.Unit[u].BumpTarget;
     96       COPY_4V(dst->Texture.Unit[u].RotMatrix, src->Texture.Unit[u].RotMatrix);
     97 
     98       /*
     99        * XXX strictly speaking, we should compare texture names/ids and
    100        * bind textures in the dest context according to id.  For now, only
    101        * copy bindings if the contexts share the same pool of textures to
    102        * avoid refcounting bugs.
    103        */
    104       if (dst->Shared == src->Shared) {
    105          /* copy texture object bindings, not contents of texture objects */
    106          _mesa_lock_context_textures(dst);
    107 
    108          for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
    109             _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
    110                                    src->Texture.Unit[u].CurrentTex[tex]);
    111          }
    112          _mesa_unlock_context_textures(dst);
    113       }
    114    }
    115 }
    116 
    117 
    118 /*
    119  * For debugging
    120  */
    121 void
    122 _mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
    123 {
    124    const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
    125    printf("Texture Unit %d\n", unit);
    126    printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
    127    printf("  GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
    128    printf("  GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
    129    printf("  GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
    130    printf("  GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
    131    printf("  GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
    132    printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
    133    printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
    134    printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
    135    printf("  GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
    136    printf("  GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
    137    printf("  GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
    138    printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
    139    printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
    140    printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
    141    printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
    142    printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
    143    printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
    144 }
    145 
    146 
    147 
    148 /**********************************************************************/
    149 /*                       Texture Environment                          */
    150 /**********************************************************************/
    151 
    152 /**
    153  * Convert "classic" texture environment to ARB_texture_env_combine style
    154  * environments.
    155  *
    156  * \param state  texture_env_combine state vector to be filled-in.
    157  * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
    158  *               \c GL_BLEND, \c GL_DECAL, etc.).
    159  * \param texBaseFormat  Base format of the texture associated with the
    160  *               texture unit.
    161  */
    162 static void
    163 calculate_derived_texenv( struct gl_tex_env_combine_state *state,
    164 			  GLenum mode, GLenum texBaseFormat )
    165 {
    166    GLenum mode_rgb;
    167    GLenum mode_a;
    168 
    169    *state = default_combine_state;
    170 
    171    switch (texBaseFormat) {
    172    case GL_ALPHA:
    173       state->SourceRGB[0] = GL_PREVIOUS;
    174       break;
    175 
    176    case GL_LUMINANCE_ALPHA:
    177    case GL_INTENSITY:
    178    case GL_RGBA:
    179       break;
    180 
    181    case GL_LUMINANCE:
    182    case GL_RED:
    183    case GL_RG:
    184    case GL_RGB:
    185    case GL_YCBCR_MESA:
    186    case GL_DUDV_ATI:
    187       state->SourceA[0] = GL_PREVIOUS;
    188       break;
    189 
    190    default:
    191       _mesa_problem(NULL,
    192                     "Invalid texBaseFormat 0x%x in calculate_derived_texenv",
    193                     texBaseFormat);
    194       return;
    195    }
    196 
    197    if (mode == GL_REPLACE_EXT)
    198       mode = GL_REPLACE;
    199 
    200    switch (mode) {
    201    case GL_REPLACE:
    202    case GL_MODULATE:
    203       mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
    204       mode_a   = mode;
    205       break;
    206 
    207    case GL_DECAL:
    208       mode_rgb = GL_INTERPOLATE;
    209       mode_a   = GL_REPLACE;
    210 
    211       state->SourceA[0] = GL_PREVIOUS;
    212 
    213       /* Having alpha / luminance / intensity textures replace using the
    214        * incoming fragment color matches the definition in NV_texture_shader.
    215        * The 1.5 spec simply marks these as "undefined".
    216        */
    217       switch (texBaseFormat) {
    218       case GL_ALPHA:
    219       case GL_LUMINANCE:
    220       case GL_LUMINANCE_ALPHA:
    221       case GL_INTENSITY:
    222 	 state->SourceRGB[0] = GL_PREVIOUS;
    223 	 break;
    224       case GL_RED:
    225       case GL_RG:
    226       case GL_RGB:
    227       case GL_YCBCR_MESA:
    228       case GL_DUDV_ATI:
    229 	 mode_rgb = GL_REPLACE;
    230 	 break;
    231       case GL_RGBA:
    232 	 state->SourceRGB[2] = GL_TEXTURE;
    233 	 break;
    234       }
    235       break;
    236 
    237    case GL_BLEND:
    238       mode_rgb = GL_INTERPOLATE;
    239       mode_a   = GL_MODULATE;
    240 
    241       switch (texBaseFormat) {
    242       case GL_ALPHA:
    243 	 mode_rgb = GL_REPLACE;
    244 	 break;
    245       case GL_INTENSITY:
    246 	 mode_a = GL_INTERPOLATE;
    247 	 state->SourceA[0] = GL_CONSTANT;
    248 	 state->OperandA[2] = GL_SRC_ALPHA;
    249 	 /* FALLTHROUGH */
    250       case GL_LUMINANCE:
    251       case GL_RED:
    252       case GL_RG:
    253       case GL_RGB:
    254       case GL_LUMINANCE_ALPHA:
    255       case GL_RGBA:
    256       case GL_YCBCR_MESA:
    257       case GL_DUDV_ATI:
    258 	 state->SourceRGB[2] = GL_TEXTURE;
    259 	 state->SourceA[2]   = GL_TEXTURE;
    260 	 state->SourceRGB[0] = GL_CONSTANT;
    261 	 state->OperandRGB[2] = GL_SRC_COLOR;
    262 	 break;
    263       }
    264       break;
    265 
    266    case GL_ADD:
    267       mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
    268       mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
    269       break;
    270 
    271    default:
    272       _mesa_problem(NULL,
    273                     "Invalid texture env mode 0x%x in calculate_derived_texenv",
    274                     mode);
    275       return;
    276    }
    277 
    278    state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
    279        ? mode_rgb : GL_REPLACE;
    280    state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
    281        ? mode_a   : GL_REPLACE;
    282 }
    283 
    284 
    285 
    286 
    287 /* GL_ARB_multitexture */
    288 void GLAPIENTRY
    289 _mesa_ActiveTextureARB(GLenum texture)
    290 {
    291    const GLuint texUnit = texture - GL_TEXTURE0;
    292    GLuint k;
    293    GET_CURRENT_CONTEXT(ctx);
    294 
    295    /* See OpenGL spec for glActiveTexture: */
    296    k = MAX2(ctx->Const.MaxCombinedTextureImageUnits,
    297             ctx->Const.MaxTextureCoordUnits);
    298 
    299    ASSERT(k <= Elements(ctx->Texture.Unit));
    300 
    301    ASSERT_OUTSIDE_BEGIN_END(ctx);
    302 
    303    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
    304       _mesa_debug(ctx, "glActiveTexture %s\n",
    305                   _mesa_lookup_enum_by_nr(texture));
    306 
    307    if (texUnit >= k) {
    308       _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
    309                   _mesa_lookup_enum_by_nr(texture));
    310       return;
    311    }
    312 
    313    if (ctx->Texture.CurrentUnit == texUnit)
    314       return;
    315 
    316    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
    317 
    318    ctx->Texture.CurrentUnit = texUnit;
    319    if (ctx->Transform.MatrixMode == GL_TEXTURE) {
    320       /* update current stack pointer */
    321       ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
    322    }
    323 }
    324 
    325 
    326 /* GL_ARB_multitexture */
    327 void GLAPIENTRY
    328 _mesa_ClientActiveTextureARB(GLenum texture)
    329 {
    330    GET_CURRENT_CONTEXT(ctx);
    331    GLuint texUnit = texture - GL_TEXTURE0;
    332    ASSERT_OUTSIDE_BEGIN_END(ctx);
    333 
    334    if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
    335       _mesa_debug(ctx, "glClientActiveTexture %s\n",
    336                   _mesa_lookup_enum_by_nr(texture));
    337 
    338    if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
    339       _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)");
    340       return;
    341    }
    342 
    343    if (ctx->Array.ActiveTexture == texUnit)
    344       return;
    345 
    346    FLUSH_VERTICES(ctx, _NEW_ARRAY);
    347    ctx->Array.ActiveTexture = texUnit;
    348 }
    349 
    350 
    351 
    352 /**********************************************************************/
    353 /*****                    State management                        *****/
    354 /**********************************************************************/
    355 
    356 
    357 /**
    358  * \note This routine refers to derived texture attribute values to
    359  * compute the ENABLE_TEXMAT flags, but is only called on
    360  * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
    361  * flags are updated by _mesa_update_textures(), below.
    362  *
    363  * \param ctx GL context.
    364  */
    365 static void
    366 update_texture_matrices( struct gl_context *ctx )
    367 {
    368    GLuint u;
    369 
    370    ctx->Texture._TexMatEnabled = 0x0;
    371 
    372    for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
    373       ASSERT(u < Elements(ctx->TextureMatrixStack));
    374       if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) {
    375 	 _math_matrix_analyse( ctx->TextureMatrixStack[u].Top );
    376 
    377 	 if (ctx->Texture.Unit[u]._ReallyEnabled &&
    378 	     ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY)
    379 	    ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u);
    380       }
    381    }
    382 }
    383 
    384 
    385 /**
    386  * Examine texture unit's combine/env state to update derived state.
    387  */
    388 static void
    389 update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
    390 {
    391    struct gl_tex_env_combine_state *combine;
    392 
    393    /* No combiners will apply to this. */
    394    if (texUnit->_Current->Target == GL_TEXTURE_BUFFER)
    395       return;
    396 
    397    /* Set the texUnit->_CurrentCombine field to point to the user's combiner
    398     * state, or the combiner state which is derived from traditional texenv
    399     * mode.
    400     */
    401    if (texUnit->EnvMode == GL_COMBINE ||
    402        texUnit->EnvMode == GL_COMBINE4_NV) {
    403       texUnit->_CurrentCombine = & texUnit->Combine;
    404    }
    405    else {
    406       const struct gl_texture_object *texObj = texUnit->_Current;
    407       GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
    408 
    409       if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) {
    410          format = texObj->DepthMode;
    411       }
    412       calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
    413       texUnit->_CurrentCombine = & texUnit->_EnvMode;
    414    }
    415 
    416    combine = texUnit->_CurrentCombine;
    417 
    418    /* Determine number of source RGB terms in the combiner function */
    419    switch (combine->ModeRGB) {
    420    case GL_REPLACE:
    421       combine->_NumArgsRGB = 1;
    422       break;
    423    case GL_ADD:
    424    case GL_ADD_SIGNED:
    425       if (texUnit->EnvMode == GL_COMBINE4_NV)
    426          combine->_NumArgsRGB = 4;
    427       else
    428          combine->_NumArgsRGB = 2;
    429       break;
    430    case GL_MODULATE:
    431    case GL_SUBTRACT:
    432    case GL_DOT3_RGB:
    433    case GL_DOT3_RGBA:
    434    case GL_DOT3_RGB_EXT:
    435    case GL_DOT3_RGBA_EXT:
    436       combine->_NumArgsRGB = 2;
    437       break;
    438    case GL_INTERPOLATE:
    439    case GL_MODULATE_ADD_ATI:
    440    case GL_MODULATE_SIGNED_ADD_ATI:
    441    case GL_MODULATE_SUBTRACT_ATI:
    442       combine->_NumArgsRGB = 3;
    443       break;
    444    case GL_BUMP_ENVMAP_ATI:
    445       /* no real arguments for this case */
    446       combine->_NumArgsRGB = 0;
    447       break;
    448    default:
    449       combine->_NumArgsRGB = 0;
    450       _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
    451       return;
    452    }
    453 
    454    /* Determine number of source Alpha terms in the combiner function */
    455    switch (combine->ModeA) {
    456    case GL_REPLACE:
    457       combine->_NumArgsA = 1;
    458       break;
    459    case GL_ADD:
    460    case GL_ADD_SIGNED:
    461       if (texUnit->EnvMode == GL_COMBINE4_NV)
    462          combine->_NumArgsA = 4;
    463       else
    464          combine->_NumArgsA = 2;
    465       break;
    466    case GL_MODULATE:
    467    case GL_SUBTRACT:
    468       combine->_NumArgsA = 2;
    469       break;
    470    case GL_INTERPOLATE:
    471    case GL_MODULATE_ADD_ATI:
    472    case GL_MODULATE_SIGNED_ADD_ATI:
    473    case GL_MODULATE_SUBTRACT_ATI:
    474       combine->_NumArgsA = 3;
    475       break;
    476    default:
    477       combine->_NumArgsA = 0;
    478       _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
    479       break;
    480    }
    481 }
    482 
    483 
    484 /**
    485  * \note This routine refers to derived texture matrix values to
    486  * compute the ENABLE_TEXMAT flags, but is only called on
    487  * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
    488  * flags are updated by _mesa_update_texture_matrices, above.
    489  *
    490  * \param ctx GL context.
    491  */
    492 static void
    493 update_texture_state( struct gl_context *ctx )
    494 {
    495    GLuint unit;
    496    struct gl_program *fprog = NULL;
    497    struct gl_program *vprog = NULL;
    498    GLbitfield enabledFragUnits = 0x0;
    499 
    500    if (ctx->Shader.CurrentVertexProgram &&
    501        ctx->Shader.CurrentVertexProgram->LinkStatus) {
    502       vprog = ctx->Shader.CurrentVertexProgram->_LinkedShaders[MESA_SHADER_VERTEX]->Program;
    503    } else if (ctx->VertexProgram._Enabled) {
    504       /* XXX enable this if/when non-shader vertex programs get
    505        * texture fetches:
    506        vprog = &ctx->VertexProgram.Current->Base;
    507        */
    508    }
    509 
    510    if (ctx->Shader.CurrentFragmentProgram &&
    511        ctx->Shader.CurrentFragmentProgram->LinkStatus) {
    512       fprog = ctx->Shader.CurrentFragmentProgram->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program;
    513    }
    514    else if (ctx->FragmentProgram._Enabled) {
    515       fprog = &ctx->FragmentProgram.Current->Base;
    516    }
    517 
    518    /* FINISHME: Geometry shader texture accesses should also be considered
    519     * FINISHME: here.
    520     */
    521 
    522    /* TODO: only set this if there are actual changes */
    523    ctx->NewState |= _NEW_TEXTURE;
    524 
    525    ctx->Texture._EnabledUnits = 0x0;
    526    ctx->Texture._GenFlags = 0x0;
    527    ctx->Texture._TexMatEnabled = 0x0;
    528    ctx->Texture._TexGenEnabled = 0x0;
    529 
    530    /*
    531     * Update texture unit state.
    532     */
    533    for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {
    534       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    535       GLbitfield enabledVertTargets = 0x0;
    536       GLbitfield enabledFragTargets = 0x0;
    537       GLbitfield enabledTargets = 0x0;
    538       GLuint texIndex;
    539 
    540       /* Get the bitmask of texture target enables.
    541        * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
    542        * which texture targets are enabled (fixed function) or referenced
    543        * by a fragment program/program.  When multiple flags are set, we'll
    544        * settle on the one with highest priority (see below).
    545        */
    546       if (vprog) {
    547          enabledVertTargets |= vprog->TexturesUsed[unit];
    548       }
    549 
    550       if (fprog) {
    551          enabledFragTargets |= fprog->TexturesUsed[unit];
    552       }
    553       else {
    554          /* fixed-function fragment program */
    555          enabledFragTargets |= texUnit->Enabled;
    556       }
    557 
    558       enabledTargets = enabledVertTargets | enabledFragTargets;
    559 
    560       texUnit->_ReallyEnabled = 0x0;
    561 
    562       if (enabledTargets == 0x0) {
    563          /* neither vertex nor fragment processing uses this unit */
    564          continue;
    565       }
    566 
    567       /* Look for the highest priority texture target that's enabled (or used
    568        * by the vert/frag shaders) and "complete".  That's the one we'll use
    569        * for texturing.  If we're using vert/frag program we're guaranteed
    570        * that bitcount(enabledBits) <= 1.
    571        * Note that the TEXTURE_x_INDEX values are in high to low priority.
    572        */
    573       for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
    574          if (enabledTargets & (1 << texIndex)) {
    575             struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
    576             struct gl_sampler_object *sampler = texUnit->Sampler ?
    577                texUnit->Sampler : &texObj->Sampler;
    578 
    579             if (!_mesa_is_texture_complete(texObj, sampler)) {
    580                _mesa_test_texobj_completeness(ctx, texObj);
    581             }
    582             if (_mesa_is_texture_complete(texObj, sampler)) {
    583                texUnit->_ReallyEnabled = 1 << texIndex;
    584                _mesa_reference_texobj(&texUnit->_Current, texObj);
    585                break;
    586             }
    587          }
    588       }
    589 
    590       if (!texUnit->_ReallyEnabled) {
    591          if (fprog) {
    592             /* If we get here it means the shader is expecting a texture
    593              * object, but there isn't one (or it's incomplete).  Use the
    594              * fallback texture.
    595              */
    596             struct gl_texture_object *texObj;
    597             gl_texture_index texTarget;
    598 
    599             assert(_mesa_bitcount(enabledTargets) == 1);
    600 
    601             texTarget = (gl_texture_index) (ffs(enabledTargets) - 1);
    602             texObj = _mesa_get_fallback_texture(ctx, texTarget);
    603 
    604             assert(texObj);
    605             if (!texObj) {
    606                /* invalid fallback texture: don't enable the texture unit */
    607                continue;
    608             }
    609 
    610             _mesa_reference_texobj(&texUnit->_Current, texObj);
    611             texUnit->_ReallyEnabled = 1 << texTarget;
    612          }
    613          else {
    614             /* fixed-function: texture unit is really disabled */
    615             continue;
    616          }
    617       }
    618 
    619       /* if we get here, we know this texture unit is enabled */
    620 
    621       ctx->Texture._EnabledUnits |= (1 << unit);
    622 
    623       if (enabledFragTargets)
    624          enabledFragUnits |= (1 << unit);
    625 
    626       update_tex_combine(ctx, texUnit);
    627    }
    628 
    629 
    630    /* Determine which texture coordinate sets are actually needed */
    631    if (fprog) {
    632       const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
    633       ctx->Texture._EnabledCoordUnits
    634          = (fprog->InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
    635    }
    636    else {
    637       ctx->Texture._EnabledCoordUnits = enabledFragUnits;
    638    }
    639 
    640    /* Setup texgen for those texture coordinate sets that are in use */
    641    for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
    642       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    643 
    644       texUnit->_GenFlags = 0x0;
    645 
    646       if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
    647 	 continue;
    648 
    649       if (texUnit->TexGenEnabled) {
    650 	 if (texUnit->TexGenEnabled & S_BIT) {
    651 	    texUnit->_GenFlags |= texUnit->GenS._ModeBit;
    652 	 }
    653 	 if (texUnit->TexGenEnabled & T_BIT) {
    654 	    texUnit->_GenFlags |= texUnit->GenT._ModeBit;
    655 	 }
    656 	 if (texUnit->TexGenEnabled & R_BIT) {
    657 	    texUnit->_GenFlags |= texUnit->GenR._ModeBit;
    658 	 }
    659 	 if (texUnit->TexGenEnabled & Q_BIT) {
    660 	    texUnit->_GenFlags |= texUnit->GenQ._ModeBit;
    661 	 }
    662 
    663 	 ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
    664 	 ctx->Texture._GenFlags |= texUnit->_GenFlags;
    665       }
    666 
    667       ASSERT(unit < Elements(ctx->TextureMatrixStack));
    668       if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
    669 	 ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
    670    }
    671 }
    672 
    673 
    674 /**
    675  * Update texture-related derived state.
    676  */
    677 void
    678 _mesa_update_texture( struct gl_context *ctx, GLuint new_state )
    679 {
    680    if (new_state & _NEW_TEXTURE_MATRIX)
    681       update_texture_matrices( ctx );
    682 
    683    if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
    684       update_texture_state( ctx );
    685 }
    686 
    687 
    688 /**********************************************************************/
    689 /*****                      Initialization                        *****/
    690 /**********************************************************************/
    691 
    692 /**
    693  * Allocate the proxy textures for the given context.
    694  *
    695  * \param ctx the context to allocate proxies for.
    696  *
    697  * \return GL_TRUE on success, or GL_FALSE on failure
    698  *
    699  * If run out of memory part way through the allocations, clean up and return
    700  * GL_FALSE.
    701  */
    702 static GLboolean
    703 alloc_proxy_textures( struct gl_context *ctx )
    704 {
    705    /* NOTE: these values must be in the same order as the TEXTURE_x_INDEX
    706     * values!
    707     */
    708    static const GLenum targets[] = {
    709       GL_TEXTURE_BUFFER,
    710       GL_TEXTURE_2D_ARRAY_EXT,
    711       GL_TEXTURE_1D_ARRAY_EXT,
    712       GL_TEXTURE_EXTERNAL_OES,
    713       GL_TEXTURE_CUBE_MAP_ARB,
    714       GL_TEXTURE_3D,
    715       GL_TEXTURE_RECTANGLE_NV,
    716       GL_TEXTURE_2D,
    717       GL_TEXTURE_1D,
    718    };
    719    GLint tgt;
    720 
    721    STATIC_ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
    722    assert(targets[TEXTURE_2D_INDEX] == GL_TEXTURE_2D);
    723    assert(targets[TEXTURE_CUBE_INDEX] == GL_TEXTURE_CUBE_MAP);
    724 
    725    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
    726       if (!(ctx->Texture.ProxyTex[tgt]
    727             = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
    728          /* out of memory, free what we did allocate */
    729          while (--tgt >= 0) {
    730             ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
    731          }
    732          return GL_FALSE;
    733       }
    734    }
    735 
    736    assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
    737    return GL_TRUE;
    738 }
    739 
    740 
    741 /**
    742  * Initialize a texture unit.
    743  *
    744  * \param ctx GL context.
    745  * \param unit texture unit number to be initialized.
    746  */
    747 static void
    748 init_texture_unit( struct gl_context *ctx, GLuint unit )
    749 {
    750    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
    751    GLuint tex;
    752 
    753    texUnit->EnvMode = GL_MODULATE;
    754    ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
    755 
    756    texUnit->Combine = default_combine_state;
    757    texUnit->_EnvMode = default_combine_state;
    758    texUnit->_CurrentCombine = & texUnit->_EnvMode;
    759    texUnit->BumpTarget = GL_TEXTURE0;
    760 
    761    texUnit->TexGenEnabled = 0x0;
    762    texUnit->GenS.Mode = GL_EYE_LINEAR;
    763    texUnit->GenT.Mode = GL_EYE_LINEAR;
    764    texUnit->GenR.Mode = GL_EYE_LINEAR;
    765    texUnit->GenQ.Mode = GL_EYE_LINEAR;
    766    texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
    767    texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
    768    texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
    769    texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
    770 
    771    /* Yes, these plane coefficients are correct! */
    772    ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
    773    ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
    774    ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
    775    ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
    776    ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
    777    ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
    778    ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
    779    ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
    780 
    781    /* no mention of this in spec, but maybe id matrix expected? */
    782    ASSIGN_4V( texUnit->RotMatrix, 1.0, 0.0, 0.0, 1.0 );
    783 
    784    /* initialize current texture object ptrs to the shared default objects */
    785    for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
    786       _mesa_reference_texobj(&texUnit->CurrentTex[tex],
    787                              ctx->Shared->DefaultTex[tex]);
    788    }
    789 }
    790 
    791 
    792 /**
    793  * Initialize texture state for the given context.
    794  */
    795 GLboolean
    796 _mesa_init_texture(struct gl_context *ctx)
    797 {
    798    GLuint u;
    799 
    800    /* Texture group */
    801    ctx->Texture.CurrentUnit = 0;      /* multitexture */
    802    ctx->Texture._EnabledUnits = 0x0;
    803 
    804    for (u = 0; u < Elements(ctx->Texture.Unit); u++)
    805       init_texture_unit(ctx, u);
    806 
    807    /* After we're done initializing the context's texture state the default
    808     * texture objects' refcounts should be at least
    809     * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
    810     */
    811    assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
    812           >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
    813 
    814    /* Allocate proxy textures */
    815    if (!alloc_proxy_textures( ctx ))
    816       return GL_FALSE;
    817 
    818    /* GL_ARB_texture_buffer_object */
    819    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
    820                                  ctx->Shared->NullBufferObj);
    821 
    822    return GL_TRUE;
    823 }
    824 
    825 
    826 /**
    827  * Free dynamically-allocted texture data attached to the given context.
    828  */
    829 void
    830 _mesa_free_texture_data(struct gl_context *ctx)
    831 {
    832    GLuint u, tgt;
    833 
    834    /* unreference current textures */
    835    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
    836       /* The _Current texture could account for another reference */
    837       _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);
    838 
    839       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
    840          _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
    841       }
    842    }
    843 
    844    /* Free proxy texture objects */
    845    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
    846       ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
    847 
    848    /* GL_ARB_texture_buffer_object */
    849    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
    850 
    851 #if FEATURE_sampler_objects
    852    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
    853       _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL);
    854    }
    855 #endif
    856 }
    857 
    858 
    859 /**
    860  * Update the default texture objects in the given context to reference those
    861  * specified in the shared state and release those referencing the old
    862  * shared state.
    863  */
    864 void
    865 _mesa_update_default_objects_texture(struct gl_context *ctx)
    866 {
    867    GLuint u, tex;
    868 
    869    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
    870       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
    871       for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
    872          _mesa_reference_texobj(&texUnit->CurrentTex[tex],
    873                                 ctx->Shared->DefaultTex[tex]);
    874       }
    875    }
    876 }
    877