Subversion Repositories Kolibri OS

Rev

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

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