2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
28 * Texture state handling.
33 #if FEATURE_colortable
39 #include "texcompress.h"
43 #include "texenvprogram.h"
45 #include "math/m_xform.h"
48 #define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X))
49 #define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X))
53 * Default texture combine environment state. This is used to initialize
54 * a context's texture units and as the basis for converting "classic"
55 * texture environmnets to ARB_texture_env_combine style values.
57 static const struct gl_tex_env_combine_state default_combine_state
= {
58 GL_MODULATE
, GL_MODULATE
,
59 { GL_TEXTURE
, GL_PREVIOUS
, GL_CONSTANT
},
60 { GL_TEXTURE
, GL_PREVIOUS
, GL_CONSTANT
},
61 { GL_SRC_COLOR
, GL_SRC_COLOR
, GL_SRC_ALPHA
},
62 { GL_SRC_ALPHA
, GL_SRC_ALPHA
, GL_SRC_ALPHA
},
69 * Copy a texture binding. Helper used by _mesa_copy_texture_state().
72 copy_texture_binding(const GLcontext
*ctx
,
73 struct gl_texture_object
**dst
,
74 struct gl_texture_object
*src
)
76 /* only copy if names differ (per OpenGL SI) */
77 if ((*dst
)->Name
!= src
->Name
) {
78 /* unbind/delete dest binding which we're changing */
80 if ((*dst
)->RefCount
== 0) {
81 /* time to delete this texture object */
82 ASSERT((*dst
)->Name
!= 0);
83 ASSERT(ctx
->Driver
.DeleteTexture
);
84 /* XXX cast-away const, unfortunately */
85 (*ctx
->Driver
.DeleteTexture
)((GLcontext
*) ctx
, *dst
);
87 /* make new binding, incrementing ref count */
95 * Used by glXCopyContext to copy texture state from one context to another.
98 _mesa_copy_texture_state( const GLcontext
*src
, GLcontext
*dst
)
105 dst
->Texture
.CurrentUnit
= src
->Texture
.CurrentUnit
;
106 dst
->Texture
._GenFlags
= src
->Texture
._GenFlags
;
107 dst
->Texture
._TexGenEnabled
= src
->Texture
._TexGenEnabled
;
108 dst
->Texture
._TexMatEnabled
= src
->Texture
._TexMatEnabled
;
109 dst
->Texture
.SharedPalette
= src
->Texture
.SharedPalette
;
112 for (i
= 0; i
< src
->Const
.MaxTextureUnits
; i
++) {
113 dst
->Texture
.Unit
[i
].Enabled
= src
->Texture
.Unit
[i
].Enabled
;
114 dst
->Texture
.Unit
[i
].EnvMode
= src
->Texture
.Unit
[i
].EnvMode
;
115 COPY_4V(dst
->Texture
.Unit
[i
].EnvColor
, src
->Texture
.Unit
[i
].EnvColor
);
116 dst
->Texture
.Unit
[i
].TexGenEnabled
= src
->Texture
.Unit
[i
].TexGenEnabled
;
117 dst
->Texture
.Unit
[i
].GenModeS
= src
->Texture
.Unit
[i
].GenModeS
;
118 dst
->Texture
.Unit
[i
].GenModeT
= src
->Texture
.Unit
[i
].GenModeT
;
119 dst
->Texture
.Unit
[i
].GenModeR
= src
->Texture
.Unit
[i
].GenModeR
;
120 dst
->Texture
.Unit
[i
].GenModeQ
= src
->Texture
.Unit
[i
].GenModeQ
;
121 dst
->Texture
.Unit
[i
]._GenBitS
= src
->Texture
.Unit
[i
]._GenBitS
;
122 dst
->Texture
.Unit
[i
]._GenBitT
= src
->Texture
.Unit
[i
]._GenBitT
;
123 dst
->Texture
.Unit
[i
]._GenBitR
= src
->Texture
.Unit
[i
]._GenBitR
;
124 dst
->Texture
.Unit
[i
]._GenBitQ
= src
->Texture
.Unit
[i
]._GenBitQ
;
125 dst
->Texture
.Unit
[i
]._GenFlags
= src
->Texture
.Unit
[i
]._GenFlags
;
126 COPY_4V(dst
->Texture
.Unit
[i
].ObjectPlaneS
, src
->Texture
.Unit
[i
].ObjectPlaneS
);
127 COPY_4V(dst
->Texture
.Unit
[i
].ObjectPlaneT
, src
->Texture
.Unit
[i
].ObjectPlaneT
);
128 COPY_4V(dst
->Texture
.Unit
[i
].ObjectPlaneR
, src
->Texture
.Unit
[i
].ObjectPlaneR
);
129 COPY_4V(dst
->Texture
.Unit
[i
].ObjectPlaneQ
, src
->Texture
.Unit
[i
].ObjectPlaneQ
);
130 COPY_4V(dst
->Texture
.Unit
[i
].EyePlaneS
, src
->Texture
.Unit
[i
].EyePlaneS
);
131 COPY_4V(dst
->Texture
.Unit
[i
].EyePlaneT
, src
->Texture
.Unit
[i
].EyePlaneT
);
132 COPY_4V(dst
->Texture
.Unit
[i
].EyePlaneR
, src
->Texture
.Unit
[i
].EyePlaneR
);
133 COPY_4V(dst
->Texture
.Unit
[i
].EyePlaneQ
, src
->Texture
.Unit
[i
].EyePlaneQ
);
134 dst
->Texture
.Unit
[i
].LodBias
= src
->Texture
.Unit
[i
].LodBias
;
136 /* GL_EXT_texture_env_combine */
137 dst
->Texture
.Unit
[i
].Combine
.ModeRGB
= src
->Texture
.Unit
[i
].Combine
.ModeRGB
;
138 dst
->Texture
.Unit
[i
].Combine
.ModeA
= src
->Texture
.Unit
[i
].Combine
.ModeA
;
139 COPY_3V(dst
->Texture
.Unit
[i
].Combine
.SourceRGB
, src
->Texture
.Unit
[i
].Combine
.SourceRGB
);
140 COPY_3V(dst
->Texture
.Unit
[i
].Combine
.SourceA
, src
->Texture
.Unit
[i
].Combine
.SourceA
);
141 COPY_3V(dst
->Texture
.Unit
[i
].Combine
.OperandRGB
, src
->Texture
.Unit
[i
].Combine
.OperandRGB
);
142 COPY_3V(dst
->Texture
.Unit
[i
].Combine
.OperandA
, src
->Texture
.Unit
[i
].Combine
.OperandA
);
143 dst
->Texture
.Unit
[i
].Combine
.ScaleShiftRGB
= src
->Texture
.Unit
[i
].Combine
.ScaleShiftRGB
;
144 dst
->Texture
.Unit
[i
].Combine
.ScaleShiftA
= src
->Texture
.Unit
[i
].Combine
.ScaleShiftA
;
146 /* copy texture object bindings, not contents of texture objects */
147 _mesa_lock_context_textures(dst
);
149 copy_texture_binding(src
, &dst
->Texture
.Unit
[i
].Current1D
,
150 src
->Texture
.Unit
[i
].Current1D
);
151 copy_texture_binding(src
, &dst
->Texture
.Unit
[i
].Current2D
,
152 src
->Texture
.Unit
[i
].Current2D
);
153 copy_texture_binding(src
, &dst
->Texture
.Unit
[i
].Current3D
,
154 src
->Texture
.Unit
[i
].Current3D
);
155 copy_texture_binding(src
, &dst
->Texture
.Unit
[i
].CurrentCubeMap
,
156 src
->Texture
.Unit
[i
].CurrentCubeMap
);
157 copy_texture_binding(src
, &dst
->Texture
.Unit
[i
].CurrentRect
,
158 src
->Texture
.Unit
[i
].CurrentRect
);
159 copy_texture_binding(src
, &dst
->Texture
.Unit
[i
].Current1DArray
,
160 src
->Texture
.Unit
[i
].Current1DArray
);
161 copy_texture_binding(src
, &dst
->Texture
.Unit
[i
].Current2DArray
,
162 src
->Texture
.Unit
[i
].Current2DArray
);
164 _mesa_unlock_context_textures(dst
);
173 _mesa_print_texunit_state( GLcontext
*ctx
, GLuint unit
)
175 const struct gl_texture_unit
*texUnit
= ctx
->Texture
.Unit
+ unit
;
176 _mesa_printf("Texture Unit %d\n", unit
);
177 _mesa_printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit
->EnvMode
));
178 _mesa_printf(" GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.ModeRGB
));
179 _mesa_printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.ModeA
));
180 _mesa_printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.SourceRGB
[0]));
181 _mesa_printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.SourceRGB
[1]));
182 _mesa_printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.SourceRGB
[2]));
183 _mesa_printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.SourceA
[0]));
184 _mesa_printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.SourceA
[1]));
185 _mesa_printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.SourceA
[2]));
186 _mesa_printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.OperandRGB
[0]));
187 _mesa_printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.OperandRGB
[1]));
188 _mesa_printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.OperandRGB
[2]));
189 _mesa_printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.OperandA
[0]));
190 _mesa_printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.OperandA
[1]));
191 _mesa_printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit
->Combine
.OperandA
[2]));
192 _mesa_printf(" GL_RGB_SCALE = %d\n", 1 << texUnit
->Combine
.ScaleShiftRGB
);
193 _mesa_printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit
->Combine
.ScaleShiftA
);
194 _mesa_printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit
->EnvColor
[0], texUnit
->EnvColor
[1], texUnit
->EnvColor
[2], texUnit
->EnvColor
[3]);
199 /**********************************************************************/
200 /* Texture Environment */
201 /**********************************************************************/
204 * Convert "classic" texture environment to ARB_texture_env_combine style
207 * \param state texture_env_combine state vector to be filled-in.
208 * \param mode Classic texture environment mode (i.e., \c GL_REPLACE,
209 * \c GL_BLEND, \c GL_DECAL, etc.).
210 * \param texBaseFormat Base format of the texture associated with the
214 calculate_derived_texenv( struct gl_tex_env_combine_state
*state
,
215 GLenum mode
, GLenum texBaseFormat
)
220 *state
= default_combine_state
;
222 switch (texBaseFormat
) {
224 state
->SourceRGB
[0] = GL_PREVIOUS
;
227 case GL_LUMINANCE_ALPHA
:
235 state
->SourceA
[0] = GL_PREVIOUS
;
239 _mesa_problem(NULL
, "Invalid texBaseFormat in calculate_derived_texenv");
243 if (mode
== GL_REPLACE_EXT
)
249 mode_rgb
= (texBaseFormat
== GL_ALPHA
) ? GL_REPLACE
: mode
;
254 mode_rgb
= GL_INTERPOLATE
;
257 state
->SourceA
[0] = GL_PREVIOUS
;
259 /* Having alpha / luminance / intensity textures replace using the
260 * incoming fragment color matches the definition in NV_texture_shader.
261 * The 1.5 spec simply marks these as "undefined".
263 switch (texBaseFormat
) {
266 case GL_LUMINANCE_ALPHA
:
268 state
->SourceRGB
[0] = GL_PREVIOUS
;
272 mode_rgb
= GL_REPLACE
;
275 state
->SourceRGB
[2] = GL_TEXTURE
;
281 mode_rgb
= GL_INTERPOLATE
;
282 mode_a
= GL_MODULATE
;
284 switch (texBaseFormat
) {
286 mode_rgb
= GL_REPLACE
;
289 mode_a
= GL_INTERPOLATE
;
290 state
->SourceA
[0] = GL_CONSTANT
;
291 state
->OperandA
[2] = GL_SRC_ALPHA
;
295 case GL_LUMINANCE_ALPHA
:
298 state
->SourceRGB
[2] = GL_TEXTURE
;
299 state
->SourceA
[2] = GL_TEXTURE
;
300 state
->SourceRGB
[0] = GL_CONSTANT
;
301 state
->OperandRGB
[2] = GL_SRC_COLOR
;
307 mode_rgb
= (texBaseFormat
== GL_ALPHA
) ? GL_REPLACE
: GL_ADD
;
308 mode_a
= (texBaseFormat
== GL_INTENSITY
) ? GL_ADD
: GL_MODULATE
;
313 "Invalid texture env mode in calculate_derived_texenv");
317 state
->ModeRGB
= (state
->SourceRGB
[0] != GL_PREVIOUS
)
318 ? mode_rgb
: GL_REPLACE
;
319 state
->ModeA
= (state
->SourceA
[0] != GL_PREVIOUS
)
320 ? mode_a
: GL_REPLACE
;
326 /* GL_ARB_multitexture */
328 _mesa_ActiveTextureARB(GLenum texture
)
330 GET_CURRENT_CONTEXT(ctx
);
331 const GLuint texUnit
= texture
- GL_TEXTURE0
;
332 ASSERT_OUTSIDE_BEGIN_END(ctx
);
334 if (MESA_VERBOSE
& (VERBOSE_API
|VERBOSE_TEXTURE
))
335 _mesa_debug(ctx
, "glActiveTexture %s\n",
336 _mesa_lookup_enum_by_nr(texture
));
338 /* XXX error-check against max(coordunits, imageunits) */
339 if (texUnit
>= ctx
->Const
.MaxTextureUnits
) {
340 _mesa_error(ctx
, GL_INVALID_ENUM
, "glActiveTexture(texture)");
344 if (ctx
->Texture
.CurrentUnit
== texUnit
)
347 FLUSH_VERTICES(ctx
, _NEW_TEXTURE
);
349 ctx
->Texture
.CurrentUnit
= texUnit
;
350 if (ctx
->Transform
.MatrixMode
== GL_TEXTURE
) {
351 /* update current stack pointer */
352 ctx
->CurrentStack
= &ctx
->TextureMatrixStack
[texUnit
];
355 if (ctx
->Driver
.ActiveTexture
) {
356 (*ctx
->Driver
.ActiveTexture
)( ctx
, (GLuint
) texUnit
);
361 /* GL_ARB_multitexture */
363 _mesa_ClientActiveTextureARB(GLenum texture
)
365 GET_CURRENT_CONTEXT(ctx
);
366 GLuint texUnit
= texture
- GL_TEXTURE0
;
367 ASSERT_OUTSIDE_BEGIN_END(ctx
);
369 if (texUnit
>= ctx
->Const
.MaxTextureCoordUnits
) {
370 _mesa_error(ctx
, GL_INVALID_ENUM
, "glClientActiveTexture(texture)");
374 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
375 ctx
->Array
.ActiveTexture
= texUnit
;
380 /**********************************************************************/
381 /***** State management *****/
382 /**********************************************************************/
386 * \note This routine refers to derived texture attribute values to
387 * compute the ENABLE_TEXMAT flags, but is only called on
388 * _NEW_TEXTURE_MATRIX. On changes to _NEW_TEXTURE, the ENABLE_TEXMAT
389 * flags are updated by _mesa_update_textures(), below.
391 * \param ctx GL context.
394 update_texture_matrices( GLcontext
*ctx
)
398 ctx
->Texture
._TexMatEnabled
= 0;
400 for (i
=0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
401 if (_math_matrix_is_dirty(ctx
->TextureMatrixStack
[i
].Top
)) {
402 _math_matrix_analyse( ctx
->TextureMatrixStack
[i
].Top
);
404 if (ctx
->Texture
.Unit
[i
]._ReallyEnabled
&&
405 ctx
->TextureMatrixStack
[i
].Top
->type
!= MATRIX_IDENTITY
)
406 ctx
->Texture
._TexMatEnabled
|= ENABLE_TEXMAT(i
);
408 if (ctx
->Driver
.TextureMatrix
)
409 ctx
->Driver
.TextureMatrix( ctx
, i
, ctx
->TextureMatrixStack
[i
].Top
);
416 * Update texture object's _Function field. We need to do this
417 * whenever any of the texture object's shadow-related fields change
418 * or when we start/stop using a fragment program.
420 * This function could be expanded someday to update additional per-object
421 * fields that depend on assorted state changes.
424 update_texture_compare_function(GLcontext
*ctx
,
425 struct gl_texture_object
*tObj
)
427 /* XXX temporarily disable this test since it breaks the GLSL
428 * shadow2D(), etc. functions.
430 if (0 /*ctx->FragmentProgram._Current*/) {
431 /* Texel/coordinate comparison is ignored for programs.
432 * See GL_ARB_fragment_program/shader spec for details.
434 tObj
->_Function
= GL_NONE
;
436 else if (tObj
->CompareFlag
) {
438 if (tObj
->CompareOperator
== GL_TEXTURE_LEQUAL_R_SGIX
) {
439 tObj
->_Function
= GL_LEQUAL
;
442 ASSERT(tObj
->CompareOperator
== GL_TEXTURE_GEQUAL_R_SGIX
);
443 tObj
->_Function
= GL_GEQUAL
;
446 else if (tObj
->CompareMode
== GL_COMPARE_R_TO_TEXTURE_ARB
) {
448 tObj
->_Function
= tObj
->CompareFunc
;
451 tObj
->_Function
= GL_NONE
; /* pass depth through as grayscale */
457 * Helper function for determining which texture object (1D, 2D, cube, etc)
458 * should actually be used.
461 texture_override(GLcontext
*ctx
,
462 struct gl_texture_unit
*texUnit
, GLbitfield enableBits
,
463 struct gl_texture_object
*texObj
, GLuint textureBit
)
465 if (!texUnit
->_ReallyEnabled
&& (enableBits
& textureBit
)) {
466 if (!texObj
->_Complete
) {
467 _mesa_test_texobj_completeness(ctx
, texObj
);
469 if (texObj
->_Complete
) {
470 texUnit
->_ReallyEnabled
= textureBit
;
471 texUnit
->_Current
= texObj
;
472 update_texture_compare_function(ctx
, texObj
);
479 * \note This routine refers to derived texture matrix values to
480 * compute the ENABLE_TEXMAT flags, but is only called on
481 * _NEW_TEXTURE. On changes to _NEW_TEXTURE_MATRIX, the ENABLE_TEXMAT
482 * flags are updated by _mesa_update_texture_matrices, above.
484 * \param ctx GL context.
487 update_texture_state( GLcontext
*ctx
)
490 struct gl_fragment_program
*fprog
= NULL
;
491 struct gl_vertex_program
*vprog
= NULL
;
493 if (ctx
->Shader
.CurrentProgram
&&
494 ctx
->Shader
.CurrentProgram
->LinkStatus
) {
495 fprog
= ctx
->Shader
.CurrentProgram
->FragmentProgram
;
496 vprog
= ctx
->Shader
.CurrentProgram
->VertexProgram
;
499 if (ctx
->FragmentProgram
._Enabled
) {
500 fprog
= ctx
->FragmentProgram
.Current
;
502 if (ctx
->VertexProgram
._Enabled
) {
503 /* XXX enable this if/when non-shader vertex programs get
505 vprog = ctx->VertexProgram.Current;
510 ctx
->NewState
|= _NEW_TEXTURE
; /* TODO: only set this if there are
514 ctx
->Texture
._EnabledUnits
= 0;
515 ctx
->Texture
._GenFlags
= 0;
516 ctx
->Texture
._TexMatEnabled
= 0;
517 ctx
->Texture
._TexGenEnabled
= 0;
520 * Update texture unit state.
522 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
523 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
524 GLbitfield enableBits
;
526 texUnit
->_Current
= NULL
;
527 texUnit
->_ReallyEnabled
= 0;
528 texUnit
->_GenFlags
= 0;
530 /* Get the bitmask of texture enables.
531 * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
532 * which texture targets are enabled (fixed function) or referenced
533 * by a fragment shader/program. When multiple flags are set, we'll
534 * settle on the one with highest priority (see texture_override below).
536 if (fprog
|| vprog
) {
539 enableBits
|= fprog
->Base
.TexturesUsed
[unit
];
541 enableBits
|= vprog
->Base
.TexturesUsed
[unit
];
544 if (!texUnit
->Enabled
)
546 enableBits
= texUnit
->Enabled
;
549 /* Look for the highest-priority texture target that's enabled and
550 * complete. That's the one we'll use for texturing. If we're using
551 * a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
553 texture_override(ctx
, texUnit
, enableBits
,
554 texUnit
->Current2DArray
, TEXTURE_2D_ARRAY_BIT
);
555 texture_override(ctx
, texUnit
, enableBits
,
556 texUnit
->Current1DArray
, TEXTURE_1D_ARRAY_BIT
);
557 texture_override(ctx
, texUnit
, enableBits
,
558 texUnit
->CurrentCubeMap
, TEXTURE_CUBE_BIT
);
559 texture_override(ctx
, texUnit
, enableBits
,
560 texUnit
->Current3D
, TEXTURE_3D_BIT
);
561 texture_override(ctx
, texUnit
, enableBits
,
562 texUnit
->CurrentRect
, TEXTURE_RECT_BIT
);
563 texture_override(ctx
, texUnit
, enableBits
,
564 texUnit
->Current2D
, TEXTURE_2D_BIT
);
565 texture_override(ctx
, texUnit
, enableBits
,
566 texUnit
->Current1D
, TEXTURE_1D_BIT
);
568 if (!texUnit
->_ReallyEnabled
) {
572 if (texUnit
->_ReallyEnabled
)
573 ctx
->Texture
._EnabledUnits
|= (1 << unit
);
575 if (texUnit
->EnvMode
== GL_COMBINE
) {
576 texUnit
->_CurrentCombine
= & texUnit
->Combine
;
579 const struct gl_texture_object
*texObj
= texUnit
->_Current
;
580 GLenum format
= texObj
->Image
[0][texObj
->BaseLevel
]->_BaseFormat
;
581 if (format
== GL_COLOR_INDEX
) {
582 format
= GL_RGBA
; /* a bit of a hack */
584 else if (format
== GL_DEPTH_COMPONENT
585 || format
== GL_DEPTH_STENCIL_EXT
) {
586 format
= texObj
->DepthMode
;
588 calculate_derived_texenv(&texUnit
->_EnvMode
, texUnit
->EnvMode
, format
);
589 texUnit
->_CurrentCombine
= & texUnit
->_EnvMode
;
592 switch (texUnit
->_CurrentCombine
->ModeRGB
) {
594 texUnit
->_CurrentCombine
->_NumArgsRGB
= 1;
602 case GL_DOT3_RGB_EXT
:
603 case GL_DOT3_RGBA_EXT
:
604 texUnit
->_CurrentCombine
->_NumArgsRGB
= 2;
607 case GL_MODULATE_ADD_ATI
:
608 case GL_MODULATE_SIGNED_ADD_ATI
:
609 case GL_MODULATE_SUBTRACT_ATI
:
610 texUnit
->_CurrentCombine
->_NumArgsRGB
= 3;
613 texUnit
->_CurrentCombine
->_NumArgsRGB
= 0;
614 _mesa_problem(ctx
, "invalid RGB combine mode in update_texture_state");
618 switch (texUnit
->_CurrentCombine
->ModeA
) {
620 texUnit
->_CurrentCombine
->_NumArgsA
= 1;
626 texUnit
->_CurrentCombine
->_NumArgsA
= 2;
629 case GL_MODULATE_ADD_ATI
:
630 case GL_MODULATE_SIGNED_ADD_ATI
:
631 case GL_MODULATE_SUBTRACT_ATI
:
632 texUnit
->_CurrentCombine
->_NumArgsA
= 3;
635 texUnit
->_CurrentCombine
->_NumArgsA
= 0;
636 _mesa_problem(ctx
, "invalid Alpha combine mode in update_texture_state");
640 if (texUnit
->TexGenEnabled
) {
641 if (texUnit
->TexGenEnabled
& S_BIT
) {
642 texUnit
->_GenFlags
|= texUnit
->_GenBitS
;
644 if (texUnit
->TexGenEnabled
& T_BIT
) {
645 texUnit
->_GenFlags
|= texUnit
->_GenBitT
;
647 if (texUnit
->TexGenEnabled
& Q_BIT
) {
648 texUnit
->_GenFlags
|= texUnit
->_GenBitQ
;
650 if (texUnit
->TexGenEnabled
& R_BIT
) {
651 texUnit
->_GenFlags
|= texUnit
->_GenBitR
;
654 ctx
->Texture
._TexGenEnabled
|= ENABLE_TEXGEN(unit
);
655 ctx
->Texture
._GenFlags
|= texUnit
->_GenFlags
;
658 if (ctx
->TextureMatrixStack
[unit
].Top
->type
!= MATRIX_IDENTITY
)
659 ctx
->Texture
._TexMatEnabled
|= ENABLE_TEXMAT(unit
);
662 /* Determine which texture coordinate sets are actually needed */
664 const GLuint coordMask
= (1 << MAX_TEXTURE_COORD_UNITS
) - 1;
665 ctx
->Texture
._EnabledCoordUnits
666 = (fprog
->Base
.InputsRead
>> FRAG_ATTRIB_TEX0
) & coordMask
;
669 ctx
->Texture
._EnabledCoordUnits
= ctx
->Texture
._EnabledUnits
;
675 * Update texture-related derived state.
678 _mesa_update_texture( GLcontext
*ctx
, GLuint new_state
)
680 if (new_state
& _NEW_TEXTURE_MATRIX
)
681 update_texture_matrices( ctx
);
683 if (new_state
& (_NEW_TEXTURE
| _NEW_PROGRAM
))
684 update_texture_state( ctx
);
688 /**********************************************************************/
689 /***** Initialization *****/
690 /**********************************************************************/
693 * Allocate the proxy textures for the given context.
695 * \param ctx the context to allocate proxies for.
697 * \return GL_TRUE on success, or GL_FALSE on failure
699 * If run out of memory part way through the allocations, clean up and return
703 alloc_proxy_textures( GLcontext
*ctx
)
705 ctx
->Texture
.Proxy1D
= (*ctx
->Driver
.NewTextureObject
)(ctx
, 0, GL_TEXTURE_1D
);
706 if (!ctx
->Texture
.Proxy1D
)
709 ctx
->Texture
.Proxy2D
= (*ctx
->Driver
.NewTextureObject
)(ctx
, 0, GL_TEXTURE_2D
);
710 if (!ctx
->Texture
.Proxy2D
)
713 ctx
->Texture
.Proxy3D
= (*ctx
->Driver
.NewTextureObject
)(ctx
, 0, GL_TEXTURE_3D
);
714 if (!ctx
->Texture
.Proxy3D
)
717 ctx
->Texture
.ProxyCubeMap
= (*ctx
->Driver
.NewTextureObject
)(ctx
, 0, GL_TEXTURE_CUBE_MAP_ARB
);
718 if (!ctx
->Texture
.ProxyCubeMap
)
721 ctx
->Texture
.ProxyRect
= (*ctx
->Driver
.NewTextureObject
)(ctx
, 0, GL_TEXTURE_RECTANGLE_NV
);
722 if (!ctx
->Texture
.ProxyRect
)
725 ctx
->Texture
.Proxy1DArray
= (*ctx
->Driver
.NewTextureObject
)(ctx
, 0, GL_TEXTURE_1D_ARRAY_EXT
);
726 if (!ctx
->Texture
.Proxy1DArray
)
729 ctx
->Texture
.Proxy2DArray
= (*ctx
->Driver
.NewTextureObject
)(ctx
, 0, GL_TEXTURE_2D_ARRAY_EXT
);
730 if (!ctx
->Texture
.Proxy2DArray
)
736 if (ctx
->Texture
.Proxy1D
)
737 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy1D
);
738 if (ctx
->Texture
.Proxy2D
)
739 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy2D
);
740 if (ctx
->Texture
.Proxy3D
)
741 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy3D
);
742 if (ctx
->Texture
.ProxyCubeMap
)
743 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.ProxyCubeMap
);
744 if (ctx
->Texture
.ProxyRect
)
745 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.ProxyRect
);
746 if (ctx
->Texture
.Proxy1DArray
)
747 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy1DArray
);
748 if (ctx
->Texture
.Proxy2DArray
)
749 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy2DArray
);
755 * Initialize a texture unit.
757 * \param ctx GL context.
758 * \param unit texture unit number to be initialized.
761 init_texture_unit( GLcontext
*ctx
, GLuint unit
)
763 struct gl_texture_unit
*texUnit
= &ctx
->Texture
.Unit
[unit
];
765 texUnit
->EnvMode
= GL_MODULATE
;
766 ASSIGN_4V( texUnit
->EnvColor
, 0.0, 0.0, 0.0, 0.0 );
768 texUnit
->Combine
= default_combine_state
;
769 texUnit
->_EnvMode
= default_combine_state
;
770 texUnit
->_CurrentCombine
= & texUnit
->_EnvMode
;
772 texUnit
->TexGenEnabled
= 0;
773 texUnit
->GenModeS
= GL_EYE_LINEAR
;
774 texUnit
->GenModeT
= GL_EYE_LINEAR
;
775 texUnit
->GenModeR
= GL_EYE_LINEAR
;
776 texUnit
->GenModeQ
= GL_EYE_LINEAR
;
777 texUnit
->_GenBitS
= TEXGEN_EYE_LINEAR
;
778 texUnit
->_GenBitT
= TEXGEN_EYE_LINEAR
;
779 texUnit
->_GenBitR
= TEXGEN_EYE_LINEAR
;
780 texUnit
->_GenBitQ
= TEXGEN_EYE_LINEAR
;
782 /* Yes, these plane coefficients are correct! */
783 ASSIGN_4V( texUnit
->ObjectPlaneS
, 1.0, 0.0, 0.0, 0.0 );
784 ASSIGN_4V( texUnit
->ObjectPlaneT
, 0.0, 1.0, 0.0, 0.0 );
785 ASSIGN_4V( texUnit
->ObjectPlaneR
, 0.0, 0.0, 0.0, 0.0 );
786 ASSIGN_4V( texUnit
->ObjectPlaneQ
, 0.0, 0.0, 0.0, 0.0 );
787 ASSIGN_4V( texUnit
->EyePlaneS
, 1.0, 0.0, 0.0, 0.0 );
788 ASSIGN_4V( texUnit
->EyePlaneT
, 0.0, 1.0, 0.0, 0.0 );
789 ASSIGN_4V( texUnit
->EyePlaneR
, 0.0, 0.0, 0.0, 0.0 );
790 ASSIGN_4V( texUnit
->EyePlaneQ
, 0.0, 0.0, 0.0, 0.0 );
792 texUnit
->Current1D
= ctx
->Shared
->Default1D
;
793 texUnit
->Current2D
= ctx
->Shared
->Default2D
;
794 texUnit
->Current3D
= ctx
->Shared
->Default3D
;
795 texUnit
->CurrentCubeMap
= ctx
->Shared
->DefaultCubeMap
;
796 texUnit
->CurrentRect
= ctx
->Shared
->DefaultRect
;
797 texUnit
->Current1DArray
= ctx
->Shared
->Default1DArray
;
798 texUnit
->Current2DArray
= ctx
->Shared
->Default2DArray
;
803 * Initialize texture state for the given context.
806 _mesa_init_texture(GLcontext
*ctx
)
810 assert(MAX_TEXTURE_LEVELS
>= MAX_3D_TEXTURE_LEVELS
);
811 assert(MAX_TEXTURE_LEVELS
>= MAX_CUBE_TEXTURE_LEVELS
);
813 /* Effectively bind the default textures to all texture units */
814 ctx
->Shared
->Default1D
->RefCount
+= MAX_TEXTURE_UNITS
;
815 ctx
->Shared
->Default2D
->RefCount
+= MAX_TEXTURE_UNITS
;
816 ctx
->Shared
->Default3D
->RefCount
+= MAX_TEXTURE_UNITS
;
817 ctx
->Shared
->DefaultCubeMap
->RefCount
+= MAX_TEXTURE_UNITS
;
818 ctx
->Shared
->DefaultRect
->RefCount
+= MAX_TEXTURE_UNITS
;
819 ctx
->Shared
->Default1DArray
->RefCount
+= MAX_TEXTURE_UNITS
;
820 ctx
->Shared
->Default2DArray
->RefCount
+= MAX_TEXTURE_UNITS
;
823 ctx
->Texture
.CurrentUnit
= 0; /* multitexture */
824 ctx
->Texture
._EnabledUnits
= 0;
825 for (i
=0; i
<MAX_TEXTURE_UNITS
; i
++)
826 init_texture_unit( ctx
, i
);
827 ctx
->Texture
.SharedPalette
= GL_FALSE
;
828 #if FEATURE_colortable
829 _mesa_init_colortable(&ctx
->Texture
.Palette
);
832 /* Allocate proxy textures */
833 if (!alloc_proxy_textures( ctx
))
841 * Free dynamically-allocted texture data attached to the given context.
844 _mesa_free_texture_data(GLcontext
*ctx
)
846 /* Free proxy texture objects */
847 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy1D
);
848 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy2D
);
849 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy3D
);
850 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.ProxyCubeMap
);
851 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.ProxyRect
);
852 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy1DArray
);
853 (ctx
->Driver
.DeleteTexture
)(ctx
, ctx
->Texture
.Proxy2DArray
);
855 #if FEATURE_colortable
858 for (i
= 0; i
< MAX_TEXTURE_IMAGE_UNITS
; i
++)
859 _mesa_free_colortable_data( &ctx
->Texture
.Unit
[i
].ColorTable
);