Subversion Repositories Kolibri OS

Rev

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

  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 "colormac.h"
  34. #include "colortab.h"
  35. #include "context.h"
  36. #include "enums.h"
  37. #include "macros.h"
  38. #include "texobj.h"
  39. #include "teximage.h"
  40. #include "texstate.h"
  41. #include "mtypes.h"
  42.  
  43.  
  44.  
  45. /**
  46.  * Default texture combine environment state.  This is used to initialize
  47.  * a context's texture units and as the basis for converting "classic"
  48.  * texture environmnets to ARB_texture_env_combine style values.
  49.  */
  50. static const struct gl_tex_env_combine_state default_combine_state = {
  51.    GL_MODULATE, GL_MODULATE,
  52.    { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
  53.    { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT, GL_CONSTANT },
  54.    { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA, GL_SRC_ALPHA },
  55.    { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA },
  56.    0, 0,
  57.    2, 2
  58. };
  59.  
  60.  
  61.  
  62. /**
  63.  * Used by glXCopyContext to copy texture state from one context to another.
  64.  */
  65. void
  66. _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst )
  67. {
  68.    GLuint u, tex;
  69.  
  70.    ASSERT(src);
  71.    ASSERT(dst);
  72.  
  73.    dst->Texture.CurrentUnit = src->Texture.CurrentUnit;
  74.    dst->Texture._GenFlags = src->Texture._GenFlags;
  75.    dst->Texture._TexGenEnabled = src->Texture._TexGenEnabled;
  76.    dst->Texture._TexMatEnabled = src->Texture._TexMatEnabled;
  77.    dst->Texture.SharedPalette = src->Texture.SharedPalette;
  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.    /* Set the texUnit->_CurrentCombine field to point to the user's combiner
  394.     * state, or the combiner state which is derived from traditional texenv
  395.     * mode.
  396.     */
  397.    if (texUnit->EnvMode == GL_COMBINE ||
  398.        texUnit->EnvMode == GL_COMBINE4_NV) {
  399.       texUnit->_CurrentCombine = & texUnit->Combine;
  400.    }
  401.    else {
  402.       const struct gl_texture_object *texObj = texUnit->_Current;
  403.       GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
  404.       if (format == GL_COLOR_INDEX) {
  405.          format = GL_RGBA;  /* a bit of a hack */
  406.       }
  407.       else if (format == GL_DEPTH_COMPONENT ||
  408.                format == GL_DEPTH_STENCIL_EXT) {
  409.          format = texObj->DepthMode;
  410.       }
  411.       calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format);
  412.       texUnit->_CurrentCombine = & texUnit->_EnvMode;
  413.    }
  414.  
  415.    combine = texUnit->_CurrentCombine;
  416.  
  417.    /* Determine number of source RGB terms in the combiner function */
  418.    switch (combine->ModeRGB) {
  419.    case GL_REPLACE:
  420.       combine->_NumArgsRGB = 1;
  421.       break;
  422.    case GL_ADD:
  423.    case GL_ADD_SIGNED:
  424.       if (texUnit->EnvMode == GL_COMBINE4_NV)
  425.          combine->_NumArgsRGB = 4;
  426.       else
  427.          combine->_NumArgsRGB = 2;
  428.       break;
  429.    case GL_MODULATE:
  430.    case GL_SUBTRACT:
  431.    case GL_DOT3_RGB:
  432.    case GL_DOT3_RGBA:
  433.    case GL_DOT3_RGB_EXT:
  434.    case GL_DOT3_RGBA_EXT:
  435.       combine->_NumArgsRGB = 2;
  436.       break;
  437.    case GL_INTERPOLATE:
  438.    case GL_MODULATE_ADD_ATI:
  439.    case GL_MODULATE_SIGNED_ADD_ATI:
  440.    case GL_MODULATE_SUBTRACT_ATI:
  441.       combine->_NumArgsRGB = 3;
  442.       break;
  443.    case GL_BUMP_ENVMAP_ATI:
  444.       /* no real arguments for this case */
  445.       combine->_NumArgsRGB = 0;
  446.       break;
  447.    default:
  448.       combine->_NumArgsRGB = 0;
  449.       _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
  450.       return;
  451.    }
  452.  
  453.    /* Determine number of source Alpha terms in the combiner function */
  454.    switch (combine->ModeA) {
  455.    case GL_REPLACE:
  456.       combine->_NumArgsA = 1;
  457.       break;
  458.    case GL_ADD:
  459.    case GL_ADD_SIGNED:
  460.       if (texUnit->EnvMode == GL_COMBINE4_NV)
  461.          combine->_NumArgsA = 4;
  462.       else
  463.          combine->_NumArgsA = 2;
  464.       break;
  465.    case GL_MODULATE:
  466.    case GL_SUBTRACT:
  467.       combine->_NumArgsA = 2;
  468.       break;
  469.    case GL_INTERPOLATE:
  470.    case GL_MODULATE_ADD_ATI:
  471.    case GL_MODULATE_SIGNED_ADD_ATI:
  472.    case GL_MODULATE_SUBTRACT_ATI:
  473.       combine->_NumArgsA = 3;
  474.       break;
  475.    default:
  476.       combine->_NumArgsA = 0;
  477.       _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
  478.       break;
  479.    }
  480. }
  481.  
  482.  
  483. /**
  484.  * \note This routine refers to derived texture matrix values to
  485.  * compute the ENABLE_TEXMAT flags, but is only called on
  486.  * _NEW_TEXTURE.  On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
  487.  * flags are updated by _mesa_update_texture_matrices, above.
  488.  *
  489.  * \param ctx GL context.
  490.  */
  491. static void
  492. update_texture_state( struct gl_context *ctx )
  493. {
  494.    GLuint unit;
  495.    struct gl_fragment_program *fprog = NULL;
  496.    struct gl_vertex_program *vprog = NULL;
  497.    GLbitfield enabledFragUnits = 0x0;
  498.  
  499.    if (ctx->Shader.CurrentVertexProgram &&
  500.        ctx->Shader.CurrentVertexProgram->LinkStatus) {
  501.       vprog = ctx->Shader.CurrentVertexProgram->VertexProgram;
  502.    } else if (ctx->VertexProgram._Enabled) {
  503.       /* XXX enable this if/when non-shader vertex programs get
  504.        * texture fetches:
  505.        vprog = ctx->VertexProgram.Current;
  506.        */
  507.    }
  508.  
  509.    if (ctx->Shader.CurrentFragmentProgram &&
  510.        ctx->Shader.CurrentFragmentProgram->LinkStatus) {
  511.       fprog = ctx->Shader.CurrentFragmentProgram->FragmentProgram;
  512.    }
  513.    else if (ctx->FragmentProgram._Enabled) {
  514.       fprog = ctx->FragmentProgram.Current;
  515.    }
  516.  
  517.    /* FINISHME: Geometry shader texture accesses should also be considered
  518.     * FINISHME: here.
  519.     */
  520.  
  521.    /* TODO: only set this if there are actual changes */
  522.    ctx->NewState |= _NEW_TEXTURE;
  523.  
  524.    ctx->Texture._EnabledUnits = 0x0;
  525.    ctx->Texture._GenFlags = 0x0;
  526.    ctx->Texture._TexMatEnabled = 0x0;
  527.    ctx->Texture._TexGenEnabled = 0x0;
  528.  
  529.    /*
  530.     * Update texture unit state.
  531.     */
  532.    for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {
  533.       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
  534.       GLbitfield enabledVertTargets = 0x0;
  535.       GLbitfield enabledFragTargets = 0x0;
  536.       GLbitfield enabledTargets = 0x0;
  537.       GLuint texIndex;
  538.  
  539.       /* Get the bitmask of texture target enables.
  540.        * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
  541.        * which texture targets are enabled (fixed function) or referenced
  542.        * by a fragment program/program.  When multiple flags are set, we'll
  543.        * settle on the one with highest priority (see below).
  544.        */
  545.       if (vprog) {
  546.          enabledVertTargets |= vprog->Base.TexturesUsed[unit];
  547.       }
  548.  
  549.       if (fprog) {
  550.          enabledFragTargets |= fprog->Base.TexturesUsed[unit];
  551.       }
  552.       else {
  553.          /* fixed-function fragment program */
  554.          enabledFragTargets |= texUnit->Enabled;
  555.       }
  556.  
  557.       enabledTargets = enabledVertTargets | enabledFragTargets;
  558.  
  559.       texUnit->_ReallyEnabled = 0x0;
  560.  
  561.       if (enabledTargets == 0x0) {
  562.          /* neither vertex nor fragment processing uses this unit */
  563.          continue;
  564.       }
  565.  
  566.       /* Look for the highest priority texture target that's enabled (or used
  567.        * by the vert/frag shaders) and "complete".  That's the one we'll use
  568.        * for texturing.  If we're using vert/frag program we're guaranteed
  569.        * that bitcount(enabledBits) <= 1.
  570.        * Note that the TEXTURE_x_INDEX values are in high to low priority.
  571.        */
  572.       for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) {
  573.          if (enabledTargets & (1 << texIndex)) {
  574.             struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex];
  575.             if (!texObj->_Complete) {
  576.                _mesa_test_texobj_completeness(ctx, texObj);
  577.             }
  578.             if (texObj->_Complete) {
  579.                texUnit->_ReallyEnabled = 1 << texIndex;
  580.                _mesa_reference_texobj(&texUnit->_Current, texObj);
  581.                break;
  582.             }
  583.          }
  584.       }
  585.  
  586.       if (!texUnit->_ReallyEnabled) {
  587.          if (fprog) {
  588.             /* If we get here it means the shader is expecting a texture
  589.              * object, but there isn't one (or it's incomplete).  Use the
  590.              * fallback texture.
  591.              */
  592.             struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx);
  593.             texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX;
  594.             _mesa_reference_texobj(&texUnit->_Current, texObj);
  595.          }
  596.          else {
  597.             /* fixed-function: texture unit is really disabled */
  598.             continue;
  599.          }
  600.       }
  601.  
  602.       /* if we get here, we know this texture unit is enabled */
  603.  
  604.       ctx->Texture._EnabledUnits |= (1 << unit);
  605.  
  606.       if (enabledFragTargets)
  607.          enabledFragUnits |= (1 << unit);
  608.  
  609.       update_tex_combine(ctx, texUnit);
  610.    }
  611.  
  612.  
  613.    /* Determine which texture coordinate sets are actually needed */
  614.    if (fprog) {
  615.       const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
  616.       ctx->Texture._EnabledCoordUnits
  617.          = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
  618.    }
  619.    else {
  620.       ctx->Texture._EnabledCoordUnits = enabledFragUnits;
  621.    }
  622.  
  623.    /* Setup texgen for those texture coordinate sets that are in use */
  624.    for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
  625.       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
  626.  
  627.       texUnit->_GenFlags = 0x0;
  628.  
  629.       if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
  630.          continue;
  631.  
  632.       if (texUnit->TexGenEnabled) {
  633.          if (texUnit->TexGenEnabled & S_BIT) {
  634.             texUnit->_GenFlags |= texUnit->GenS._ModeBit;
  635.          }
  636.          if (texUnit->TexGenEnabled & T_BIT) {
  637.             texUnit->_GenFlags |= texUnit->GenT._ModeBit;
  638.          }
  639.          if (texUnit->TexGenEnabled & R_BIT) {
  640.             texUnit->_GenFlags |= texUnit->GenR._ModeBit;
  641.          }
  642.          if (texUnit->TexGenEnabled & Q_BIT) {
  643.             texUnit->_GenFlags |= texUnit->GenQ._ModeBit;
  644.          }
  645.  
  646.          ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
  647.          ctx->Texture._GenFlags |= texUnit->_GenFlags;
  648.       }
  649.  
  650.       ASSERT(unit < Elements(ctx->TextureMatrixStack));
  651.       if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
  652.          ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
  653.    }
  654. }
  655.  
  656.  
  657. /**
  658.  * Update texture-related derived state.
  659.  */
  660. void
  661. _mesa_update_texture( struct gl_context *ctx, GLuint new_state )
  662. {
  663.    if (new_state & _NEW_TEXTURE_MATRIX)
  664.       update_texture_matrices( ctx );
  665.  
  666.    if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
  667.       update_texture_state( ctx );
  668. }
  669.  
  670.  
  671. /**********************************************************************/
  672. /*****                      Initialization                        *****/
  673. /**********************************************************************/
  674.  
  675. /**
  676.  * Allocate the proxy textures for the given context.
  677.  *
  678.  * \param ctx the context to allocate proxies for.
  679.  *
  680.  * \return GL_TRUE on success, or GL_FALSE on failure
  681.  *
  682.  * If run out of memory part way through the allocations, clean up and return
  683.  * GL_FALSE.
  684.  */
  685. static GLboolean
  686. alloc_proxy_textures( struct gl_context *ctx )
  687. {
  688.    static const GLenum targets[] = {
  689.       GL_TEXTURE_1D,
  690.       GL_TEXTURE_2D,
  691.       GL_TEXTURE_3D,
  692.       GL_TEXTURE_CUBE_MAP_ARB,
  693.       GL_TEXTURE_RECTANGLE_NV,
  694.       GL_TEXTURE_1D_ARRAY_EXT,
  695.       GL_TEXTURE_2D_ARRAY_EXT
  696.    };
  697.    GLint tgt;
  698.  
  699.    ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
  700.  
  701.    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
  702.       if (!(ctx->Texture.ProxyTex[tgt]
  703.             = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
  704.          /* out of memory, free what we did allocate */
  705.          while (--tgt >= 0) {
  706.             ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
  707.          }
  708.          return GL_FALSE;
  709.       }
  710.    }
  711.  
  712.    assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
  713.    return GL_TRUE;
  714. }
  715.  
  716.  
  717. /**
  718.  * Initialize a texture unit.
  719.  *
  720.  * \param ctx GL context.
  721.  * \param unit texture unit number to be initialized.
  722.  */
  723. static void
  724. init_texture_unit( struct gl_context *ctx, GLuint unit )
  725. {
  726.    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
  727.    GLuint tex;
  728.  
  729.    texUnit->EnvMode = GL_MODULATE;
  730.    ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
  731.  
  732.    texUnit->Combine = default_combine_state;
  733.    texUnit->_EnvMode = default_combine_state;
  734.    texUnit->_CurrentCombine = & texUnit->_EnvMode;
  735.    texUnit->BumpTarget = GL_TEXTURE0;
  736.  
  737.    texUnit->TexGenEnabled = 0x0;
  738.    texUnit->GenS.Mode = GL_EYE_LINEAR;
  739.    texUnit->GenT.Mode = GL_EYE_LINEAR;
  740.    texUnit->GenR.Mode = GL_EYE_LINEAR;
  741.    texUnit->GenQ.Mode = GL_EYE_LINEAR;
  742.    texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
  743.    texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
  744.    texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
  745.    texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
  746.  
  747.    /* Yes, these plane coefficients are correct! */
  748.    ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
  749.    ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
  750.    ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
  751.    ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
  752.    ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
  753.    ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
  754.    ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
  755.    ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
  756.  
  757.    /* no mention of this in spec, but maybe id matrix expected? */
  758.    ASSIGN_4V( texUnit->RotMatrix, 1.0, 0.0, 0.0, 1.0 );
  759.  
  760.    /* initialize current texture object ptrs to the shared default objects */
  761.    for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
  762.       _mesa_reference_texobj(&texUnit->CurrentTex[tex],
  763.                              ctx->Shared->DefaultTex[tex]);
  764.    }
  765. }
  766.  
  767.  
  768. /**
  769.  * Initialize texture state for the given context.
  770.  */
  771. GLboolean
  772. _mesa_init_texture(struct gl_context *ctx)
  773. {
  774.    GLuint u;
  775.  
  776.    /* Texture group */
  777.    ctx->Texture.CurrentUnit = 0;      /* multitexture */
  778.    ctx->Texture._EnabledUnits = 0x0;
  779.    ctx->Texture.SharedPalette = GL_FALSE;
  780.    _mesa_init_colortable(&ctx->Texture.Palette);
  781.  
  782.    for (u = 0; u < Elements(ctx->Texture.Unit); u++)
  783.       init_texture_unit(ctx, u);
  784.  
  785.    /* After we're done initializing the context's texture state the default
  786.     * texture objects' refcounts should be at least
  787.     * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
  788.     */
  789.    assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
  790.           >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
  791.  
  792.    /* Allocate proxy textures */
  793.    if (!alloc_proxy_textures( ctx ))
  794.       return GL_FALSE;
  795.  
  796.    return GL_TRUE;
  797. }
  798.  
  799.  
  800. /**
  801.  * Free dynamically-allocted texture data attached to the given context.
  802.  */
  803. void
  804. _mesa_free_texture_data(struct gl_context *ctx)
  805. {
  806.    GLuint u, tgt;
  807.  
  808.    /* unreference current textures */
  809.    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
  810.       /* The _Current texture could account for another reference */
  811.       _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);
  812.  
  813.       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
  814.          _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
  815.       }
  816.    }
  817.  
  818.    /* Free proxy texture objects */
  819.    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
  820.       ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
  821.  
  822.    for (u = 0; u < Elements(ctx->Texture.Unit); u++)
  823.       _mesa_free_colortable_data(&ctx->Texture.Unit[u].ColorTable);
  824. }
  825.  
  826.  
  827. /**
  828.  * Update the default texture objects in the given context to reference those
  829.  * specified in the shared state and release those referencing the old
  830.  * shared state.
  831.  */
  832. void
  833. _mesa_update_default_objects_texture(struct gl_context *ctx)
  834. {
  835.    GLuint u, tex;
  836.  
  837.    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
  838.       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
  839.       for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
  840.          _mesa_reference_texobj(&texUnit->CurrentTex[tex],
  841.                                 ctx->Shared->DefaultTex[tex]);
  842.       }
  843.    }
  844. }
  845.