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