Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / main / texstate.c
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    dst->Texture.SharedPalette = src->Texture.SharedPalette;
79
80    /* per-unit state */
81    for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
82       dst->Texture.Unit[u].Enabled = src->Texture.Unit[u].Enabled;
83       dst->Texture.Unit[u].EnvMode = src->Texture.Unit[u].EnvMode;
84       COPY_4V(dst->Texture.Unit[u].EnvColor, src->Texture.Unit[u].EnvColor);
85       dst->Texture.Unit[u].TexGenEnabled = src->Texture.Unit[u].TexGenEnabled;
86       dst->Texture.Unit[u].GenS = src->Texture.Unit[u].GenS;
87       dst->Texture.Unit[u].GenT = src->Texture.Unit[u].GenT;
88       dst->Texture.Unit[u].GenR = src->Texture.Unit[u].GenR;
89       dst->Texture.Unit[u].GenQ = src->Texture.Unit[u].GenQ;
90       dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias;
91
92       /* GL_EXT_texture_env_combine */
93       dst->Texture.Unit[u].Combine = src->Texture.Unit[u].Combine;
94
95       /* GL_ATI_envmap_bumpmap - need this? */
96       dst->Texture.Unit[u].BumpTarget = src->Texture.Unit[u].BumpTarget;
97       COPY_4V(dst->Texture.Unit[u].RotMatrix, src->Texture.Unit[u].RotMatrix);
98
99       /*
100        * XXX strictly speaking, we should compare texture names/ids and
101        * bind textures in the dest context according to id.  For now, only
102        * copy bindings if the contexts share the same pool of textures to
103        * avoid refcounting bugs.
104        */
105       if (dst->Shared == src->Shared) {
106          /* copy texture object bindings, not contents of texture objects */
107          _mesa_lock_context_textures(dst);
108
109          for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
110             _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
111                                    src->Texture.Unit[u].CurrentTex[tex]);
112          }
113          _mesa_unlock_context_textures(dst);
114       }
115    }
116 }
117
118
119 /*
120  * For debugging
121  */
122 void
123 _mesa_print_texunit_state( struct gl_context *ctx, GLuint unit )
124 {
125    const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
126    printf("Texture Unit %d\n", unit);
127    printf("  GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
128    printf("  GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
129    printf("  GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
130    printf("  GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
131    printf("  GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
132    printf("  GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
133    printf("  GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
134    printf("  GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
135    printf("  GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
136    printf("  GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
137    printf("  GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
138    printf("  GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
139    printf("  GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
140    printf("  GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
141    printf("  GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
142    printf("  GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
143    printf("  GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
144    printf("  GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
145 }
146
147
148
149 /**********************************************************************/
150 /*                       Texture Environment                          */
151 /**********************************************************************/
152
153 /**
154  * Convert "classic" texture environment to ARB_texture_env_combine style
155  * environments.
156  * 
157  * \param state  texture_env_combine state vector to be filled-in.
158  * \param mode   Classic texture environment mode (i.e., \c GL_REPLACE,
159  *               \c GL_BLEND, \c GL_DECAL, etc.).
160  * \param texBaseFormat  Base format of the texture associated with the
161  *               texture unit.
162  */
163 static void
164 calculate_derived_texenv( struct gl_tex_env_combine_state *state,
165                           GLenum mode, GLenum texBaseFormat )
166 {
167    GLenum mode_rgb;
168    GLenum mode_a;
169
170    *state = default_combine_state;
171
172    switch (texBaseFormat) {
173    case GL_ALPHA:
174       state->SourceRGB[0] = GL_PREVIOUS;
175       break;
176
177    case GL_LUMINANCE_ALPHA:
178    case GL_INTENSITY:
179    case GL_RGBA:
180       break;
181
182    case GL_LUMINANCE:
183    case GL_RED:
184    case GL_RG:
185    case GL_RGB:
186    case GL_YCBCR_MESA:
187    case GL_DUDV_ATI:
188       state->SourceA[0] = GL_PREVIOUS;
189       break;
190       
191    default:
192       _mesa_problem(NULL,
193                     "Invalid texBaseFormat 0x%x in calculate_derived_texenv",
194                     texBaseFormat);
195       return;
196    }
197
198    if (mode == GL_REPLACE_EXT)
199       mode = GL_REPLACE;
200
201    switch (mode) {
202    case GL_REPLACE:
203    case GL_MODULATE:
204       mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
205       mode_a   = mode;
206       break;
207    
208    case GL_DECAL:
209       mode_rgb = GL_INTERPOLATE;
210       mode_a   = GL_REPLACE;
211
212       state->SourceA[0] = GL_PREVIOUS;
213
214       /* Having alpha / luminance / intensity textures replace using the
215        * incoming fragment color matches the definition in NV_texture_shader.
216        * The 1.5 spec simply marks these as "undefined".
217        */
218       switch (texBaseFormat) {
219       case GL_ALPHA:
220       case GL_LUMINANCE:
221       case GL_LUMINANCE_ALPHA:
222       case GL_INTENSITY:
223          state->SourceRGB[0] = GL_PREVIOUS;
224          break;
225       case GL_RED:
226       case GL_RG:
227       case GL_RGB:
228       case GL_YCBCR_MESA:
229       case GL_DUDV_ATI:
230          mode_rgb = GL_REPLACE;
231          break;
232       case GL_RGBA:
233          state->SourceRGB[2] = GL_TEXTURE;
234          break;
235       }
236       break;
237
238    case GL_BLEND:
239       mode_rgb = GL_INTERPOLATE;
240       mode_a   = GL_MODULATE;
241
242       switch (texBaseFormat) {
243       case GL_ALPHA:
244          mode_rgb = GL_REPLACE;
245          break;
246       case GL_INTENSITY:
247          mode_a = GL_INTERPOLATE;
248          state->SourceA[0] = GL_CONSTANT;
249          state->OperandA[2] = GL_SRC_ALPHA;
250          /* FALLTHROUGH */
251       case GL_LUMINANCE:
252       case GL_RED:
253       case GL_RG:
254       case GL_RGB:
255       case GL_LUMINANCE_ALPHA:
256       case GL_RGBA:
257       case GL_YCBCR_MESA:
258       case GL_DUDV_ATI:
259          state->SourceRGB[2] = GL_TEXTURE;
260          state->SourceA[2]   = GL_TEXTURE;
261          state->SourceRGB[0] = GL_CONSTANT;
262          state->OperandRGB[2] = GL_SRC_COLOR;
263          break;
264       }
265       break;
266
267    case GL_ADD:
268       mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
269       mode_a   = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
270       break;
271
272    default:
273       _mesa_problem(NULL,
274                     "Invalid texture env mode 0x%x in calculate_derived_texenv",
275                     mode);
276       return;
277    }
278    
279    state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS)
280        ? mode_rgb : GL_REPLACE;
281    state->ModeA   = (state->SourceA[0]   != GL_PREVIOUS)
282        ? mode_a   : GL_REPLACE;
283 }
284
285
286
287
288 /* GL_ARB_multitexture */
289 void GLAPIENTRY
290 _mesa_ActiveTextureARB(GLenum texture)
291 {
292    const GLuint texUnit = texture - GL_TEXTURE0;
293    GLuint k;
294    GET_CURRENT_CONTEXT(ctx);
295
296    /* See OpenGL spec for glActiveTexture: */
297    k = MAX2(ctx->Const.MaxCombinedTextureImageUnits,
298             ctx->Const.MaxTextureCoordUnits);
299
300    ASSERT(k <= Elements(ctx->Texture.Unit));
301    
302    ASSERT_OUTSIDE_BEGIN_END(ctx);
303
304    if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
305       _mesa_debug(ctx, "glActiveTexture %s\n",
306                   _mesa_lookup_enum_by_nr(texture));
307
308    if (texUnit >= k) {
309       _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
310                   _mesa_lookup_enum_by_nr(texture));
311       return;
312    }
313
314    if (ctx->Texture.CurrentUnit == texUnit)
315       return;
316
317    FLUSH_VERTICES(ctx, _NEW_TEXTURE);
318
319    ctx->Texture.CurrentUnit = texUnit;
320    if (ctx->Transform.MatrixMode == GL_TEXTURE) {
321       /* update current stack pointer */
322       ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
323    }
324 }
325
326
327 /* GL_ARB_multitexture */
328 void GLAPIENTRY
329 _mesa_ClientActiveTextureARB(GLenum texture)
330 {
331    GET_CURRENT_CONTEXT(ctx);
332    GLuint texUnit = texture - GL_TEXTURE0;
333    ASSERT_OUTSIDE_BEGIN_END(ctx);
334
335    if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
336       _mesa_debug(ctx, "glClientActiveTexture %s\n",
337                   _mesa_lookup_enum_by_nr(texture));
338
339    if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
340       _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)");
341       return;
342    }
343
344    if (ctx->Array.ActiveTexture == texUnit)
345       return;
346
347    FLUSH_VERTICES(ctx, _NEW_ARRAY);
348    ctx->Array.ActiveTexture = texUnit;
349 }
350
351
352
353 /**********************************************************************/
354 /*****                    State management                        *****/
355 /**********************************************************************/
356
357
358 /**
359  * \note This routine refers to derived texture attribute values to
360  * compute the ENABLE_TEXMAT flags, but is only called on
361  * _NEW_TEXTURE_MATRIX.  On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
362  * flags are updated by _mesa_update_textures(), below.
363  *
364  * \param ctx GL context.
365  */
366 static void
367 update_texture_matrices( struct gl_context *ctx )
368 {
369    GLuint u;
370
371    ctx->Texture._TexMatEnabled = 0x0;
372
373    for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
374       ASSERT(u < Elements(ctx->TextureMatrixStack));
375       if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) {
376          _math_matrix_analyse( ctx->TextureMatrixStack[u].Top );
377
378          if (ctx->Texture.Unit[u]._ReallyEnabled &&
379              ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY)
380             ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u);
381       }
382    }
383 }
384
385
386 /**
387  * Examine texture unit's combine/env state to update derived state.
388  */
389 static void
390 update_tex_combine(struct gl_context *ctx, struct gl_texture_unit *texUnit)
391 {
392    struct gl_tex_env_combine_state *combine;
393
394    /* Set the texUnit->_CurrentCombine field to point to the user's combiner
395     * state, or the combiner state which is derived from traditional texenv
396     * mode.
397     */
398    if (texUnit->EnvMode == GL_COMBINE ||
399        texUnit->EnvMode == GL_COMBINE4_NV) {
400       texUnit->_CurrentCombine = & texUnit->Combine;
401    }
402    else {
403       const struct gl_texture_object *texObj = texUnit->_Current;
404       GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
405       if (format == GL_COLOR_INDEX) {
406          format = GL_RGBA;  /* a bit of a hack */
407       }
408       else if (format == GL_DEPTH_COMPONENT ||
409                format == GL_DEPTH_STENCIL_EXT) {
410          format = texObj->Sampler.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_fragment_program *fprog = NULL;
497    struct gl_vertex_program *vprog = NULL;
498    GLbitfield enabledFragUnits = 0x0;
499
500    if (ctx->Shader.CurrentVertexProgram &&
501        ctx->Shader.CurrentVertexProgram->LinkStatus) {
502       vprog = ctx->Shader.CurrentVertexProgram->VertexProgram;
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;
507        */
508    }
509
510    if (ctx->Shader.CurrentFragmentProgram &&
511        ctx->Shader.CurrentFragmentProgram->LinkStatus) {
512       fprog = ctx->Shader.CurrentFragmentProgram->FragmentProgram;
513    }
514    else if (ctx->FragmentProgram._Enabled) {
515       fprog = ctx->FragmentProgram.Current;
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->Base.TexturesUsed[unit];
548       }
549
550       if (fprog) {
551          enabledFragTargets |= fprog->Base.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             if (!texObj->_Complete) {
577                _mesa_test_texobj_completeness(ctx, texObj);
578             }
579             if (texObj->_Complete) {
580                texUnit->_ReallyEnabled = 1 << texIndex;
581                _mesa_reference_texobj(&texUnit->_Current, texObj);
582                break;
583             }
584          }
585       }
586
587       if (!texUnit->_ReallyEnabled) {
588          if (fprog) {
589             /* If we get here it means the shader is expecting a texture
590              * object, but there isn't one (or it's incomplete).  Use the
591              * fallback texture.
592              */
593             struct gl_texture_object *texObj = _mesa_get_fallback_texture(ctx);
594             texUnit->_ReallyEnabled = 1 << TEXTURE_2D_INDEX;
595             _mesa_reference_texobj(&texUnit->_Current, texObj);
596          }
597          else {
598             /* fixed-function: texture unit is really disabled */
599             continue;
600          }
601       }
602
603       /* if we get here, we know this texture unit is enabled */
604
605       ctx->Texture._EnabledUnits |= (1 << unit);
606
607       if (enabledFragTargets)
608          enabledFragUnits |= (1 << unit);
609
610       update_tex_combine(ctx, texUnit);
611    }
612
613
614    /* Determine which texture coordinate sets are actually needed */
615    if (fprog) {
616       const GLuint coordMask = (1 << MAX_TEXTURE_COORD_UNITS) - 1;
617       ctx->Texture._EnabledCoordUnits
618          = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
619    }
620    else {
621       ctx->Texture._EnabledCoordUnits = enabledFragUnits;
622    }
623
624    /* Setup texgen for those texture coordinate sets that are in use */
625    for (unit = 0; unit < ctx->Const.MaxTextureCoordUnits; unit++) {
626       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
627
628       texUnit->_GenFlags = 0x0;
629
630       if (!(ctx->Texture._EnabledCoordUnits & (1 << unit)))
631          continue;
632
633       if (texUnit->TexGenEnabled) {
634          if (texUnit->TexGenEnabled & S_BIT) {
635             texUnit->_GenFlags |= texUnit->GenS._ModeBit;
636          }
637          if (texUnit->TexGenEnabled & T_BIT) {
638             texUnit->_GenFlags |= texUnit->GenT._ModeBit;
639          }
640          if (texUnit->TexGenEnabled & R_BIT) {
641             texUnit->_GenFlags |= texUnit->GenR._ModeBit;
642          }
643          if (texUnit->TexGenEnabled & Q_BIT) {
644             texUnit->_GenFlags |= texUnit->GenQ._ModeBit;
645          }
646
647          ctx->Texture._TexGenEnabled |= ENABLE_TEXGEN(unit);
648          ctx->Texture._GenFlags |= texUnit->_GenFlags;
649       }
650
651       ASSERT(unit < Elements(ctx->TextureMatrixStack));
652       if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
653          ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
654    }
655 }
656
657
658 /**
659  * Update texture-related derived state.
660  */
661 void
662 _mesa_update_texture( struct gl_context *ctx, GLuint new_state )
663 {
664    if (new_state & _NEW_TEXTURE_MATRIX)
665       update_texture_matrices( ctx );
666
667    if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM))
668       update_texture_state( ctx );
669 }
670
671
672 /**********************************************************************/
673 /*****                      Initialization                        *****/
674 /**********************************************************************/
675
676 /**
677  * Allocate the proxy textures for the given context.
678  * 
679  * \param ctx the context to allocate proxies for.
680  * 
681  * \return GL_TRUE on success, or GL_FALSE on failure
682  * 
683  * If run out of memory part way through the allocations, clean up and return
684  * GL_FALSE.
685  */
686 static GLboolean
687 alloc_proxy_textures( struct gl_context *ctx )
688 {
689    static const GLenum targets[] = {
690       GL_TEXTURE_1D,
691       GL_TEXTURE_2D,
692       GL_TEXTURE_3D,
693       GL_TEXTURE_CUBE_MAP_ARB,
694       GL_TEXTURE_RECTANGLE_NV,
695       GL_TEXTURE_1D_ARRAY_EXT,
696       GL_TEXTURE_2D_ARRAY_EXT,
697       GL_TEXTURE_BUFFER
698    };
699    GLint tgt;
700
701    ASSERT(Elements(targets) == NUM_TEXTURE_TARGETS);
702
703    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
704       if (!(ctx->Texture.ProxyTex[tgt]
705             = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) {
706          /* out of memory, free what we did allocate */
707          while (--tgt >= 0) {
708             ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
709          }
710          return GL_FALSE;
711       }
712    }
713
714    assert(ctx->Texture.ProxyTex[0]->RefCount == 1); /* sanity check */
715    return GL_TRUE;
716 }
717
718
719 /**
720  * Initialize a texture unit.
721  *
722  * \param ctx GL context.
723  * \param unit texture unit number to be initialized.
724  */
725 static void
726 init_texture_unit( struct gl_context *ctx, GLuint unit )
727 {
728    struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
729    GLuint tex;
730
731    texUnit->EnvMode = GL_MODULATE;
732    ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 );
733
734    texUnit->Combine = default_combine_state;
735    texUnit->_EnvMode = default_combine_state;
736    texUnit->_CurrentCombine = & texUnit->_EnvMode;
737    texUnit->BumpTarget = GL_TEXTURE0;
738
739    texUnit->TexGenEnabled = 0x0;
740    texUnit->GenS.Mode = GL_EYE_LINEAR;
741    texUnit->GenT.Mode = GL_EYE_LINEAR;
742    texUnit->GenR.Mode = GL_EYE_LINEAR;
743    texUnit->GenQ.Mode = GL_EYE_LINEAR;
744    texUnit->GenS._ModeBit = TEXGEN_EYE_LINEAR;
745    texUnit->GenT._ModeBit = TEXGEN_EYE_LINEAR;
746    texUnit->GenR._ModeBit = TEXGEN_EYE_LINEAR;
747    texUnit->GenQ._ModeBit = TEXGEN_EYE_LINEAR;
748
749    /* Yes, these plane coefficients are correct! */
750    ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
751    ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
752    ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
753    ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
754    ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
755    ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
756    ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
757    ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
758
759    /* no mention of this in spec, but maybe id matrix expected? */
760    ASSIGN_4V( texUnit->RotMatrix, 1.0, 0.0, 0.0, 1.0 );
761
762    /* initialize current texture object ptrs to the shared default objects */
763    for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
764       _mesa_reference_texobj(&texUnit->CurrentTex[tex],
765                              ctx->Shared->DefaultTex[tex]);
766    }
767 }
768
769
770 /**
771  * Initialize texture state for the given context.
772  */
773 GLboolean
774 _mesa_init_texture(struct gl_context *ctx)
775 {
776    GLuint u;
777
778    /* Texture group */
779    ctx->Texture.CurrentUnit = 0;      /* multitexture */
780    ctx->Texture._EnabledUnits = 0x0;
781    ctx->Texture.SharedPalette = GL_FALSE;
782    _mesa_init_colortable(&ctx->Texture.Palette);
783
784    for (u = 0; u < Elements(ctx->Texture.Unit); u++)
785       init_texture_unit(ctx, u);
786
787    /* After we're done initializing the context's texture state the default
788     * texture objects' refcounts should be at least
789     * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
790     */
791    assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
792           >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
793
794    /* Allocate proxy textures */
795    if (!alloc_proxy_textures( ctx ))
796       return GL_FALSE;
797
798    /* GL_ARB_texture_buffer_object */
799    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject,
800                                  ctx->Shared->NullBufferObj);
801
802    return GL_TRUE;
803 }
804
805
806 /**
807  * Free dynamically-allocted texture data attached to the given context.
808  */
809 void
810 _mesa_free_texture_data(struct gl_context *ctx)
811 {
812    GLuint u, tgt;
813
814    /* unreference current textures */
815    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
816       /* The _Current texture could account for another reference */
817       _mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);
818
819       for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
820          _mesa_reference_texobj(&ctx->Texture.Unit[u].CurrentTex[tgt], NULL);
821       }
822    }
823
824    /* Free proxy texture objects */
825    for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
826       ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
827
828    /* GL_ARB_texture_buffer_object */
829    _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL);
830
831 #if FEATURE_sampler_objects
832    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
833       _mesa_reference_sampler_object(ctx, &ctx->Texture.Unit[u].Sampler, NULL);
834    }
835 #endif
836 }
837
838
839 /**
840  * Update the default texture objects in the given context to reference those
841  * specified in the shared state and release those referencing the old 
842  * shared state.
843  */
844 void
845 _mesa_update_default_objects_texture(struct gl_context *ctx)
846 {
847    GLuint u, tex;
848
849    for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
850       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
851       for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
852          _mesa_reference_texobj(&texUnit->CurrentTex[tex],
853                                 ctx->Shared->DefaultTex[tex]);
854       }
855    }
856 }