OSDN Git Service

mesa: remove outdated version lines in comments
[android-x86/external-mesa.git] / src / mesa / main / texstate.c
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 }