#include "glheader.h"
#include "mfeatures.h"
#include "colormac.h"
-#if FEATURE_colortable
#include "colortab.h"
-#endif
#include "context.h"
#include "enums.h"
#include "macros.h"
-#include "texcompress.h"
#include "texobj.h"
#include "teximage.h"
#include "texstate.h"
-#include "texenvprogram.h"
#include "mtypes.h"
dst->Texture.SharedPalette = src->Texture.SharedPalette;
/* per-unit state */
- for (u = 0; u < src->Const.MaxTextureImageUnits; u++) {
+ for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) {
dst->Texture.Unit[u].Enabled = src->Texture.Unit[u].Enabled;
dst->Texture.Unit[u].EnvMode = src->Texture.Unit[u].EnvMode;
COPY_4V(dst->Texture.Unit[u].EnvColor, src->Texture.Unit[u].EnvColor);
dst->Texture.Unit[u].BumpTarget = src->Texture.Unit[u].BumpTarget;
COPY_4V(dst->Texture.Unit[u].RotMatrix, src->Texture.Unit[u].RotMatrix);
+ /*
+ * XXX strictly speaking, we should compare texture names/ids and
+ * bind textures in the dest context according to id. For now, only
+ * copy bindings if the contexts share the same pool of textures to
+ * avoid refcounting bugs.
+ */
+ if (dst->Shared == src->Shared) {
+ /* copy texture object bindings, not contents of texture objects */
+ _mesa_lock_context_textures(dst);
- /* copy texture object bindings, not contents of texture objects */
- _mesa_lock_context_textures(dst);
-
- for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
- _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
- src->Texture.Unit[u].CurrentTex[tex]);
+ for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
+ _mesa_reference_texobj(&dst->Texture.Unit[u].CurrentTex[tex],
+ src->Texture.Unit[u].CurrentTex[tex]);
+ }
+ _mesa_unlock_context_textures(dst);
}
-
- _mesa_unlock_context_textures(dst);
}
}
_mesa_print_texunit_state( GLcontext *ctx, GLuint unit )
{
const struct gl_texture_unit *texUnit = ctx->Texture.Unit + unit;
- _mesa_printf("Texture Unit %d\n", unit);
- _mesa_printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
- _mesa_printf(" GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
- _mesa_printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
- _mesa_printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
- _mesa_printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
- _mesa_printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
- _mesa_printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
- _mesa_printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
- _mesa_printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
- _mesa_printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
- _mesa_printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
- _mesa_printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
- _mesa_printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
- _mesa_printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
- _mesa_printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
- _mesa_printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
- _mesa_printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
- _mesa_printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
+ printf("Texture Unit %d\n", unit);
+ printf(" GL_TEXTURE_ENV_MODE = %s\n", _mesa_lookup_enum_by_nr(texUnit->EnvMode));
+ printf(" GL_COMBINE_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeRGB));
+ printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.ModeA));
+ printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[0]));
+ printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[1]));
+ printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceRGB[2]));
+ printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[0]));
+ printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[1]));
+ printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.SourceA[2]));
+ printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[0]));
+ printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[1]));
+ printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandRGB[2]));
+ printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[0]));
+ printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[1]));
+ printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->Combine.OperandA[2]));
+ printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftRGB);
+ printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->Combine.ScaleShiftA);
+ printf(" GL_TEXTURE_ENV_COLOR = (%f, %f, %f, %f)\n", texUnit->EnvColor[0], texUnit->EnvColor[1], texUnit->EnvColor[2], texUnit->EnvColor[3]);
}
void GLAPIENTRY
_mesa_ActiveTextureARB(GLenum texture)
{
- GET_CURRENT_CONTEXT(ctx);
const GLuint texUnit = texture - GL_TEXTURE0;
+ GLuint k;
+ GET_CURRENT_CONTEXT(ctx);
+
+ /* See OpenGL spec for glActiveTexture: */
+ k = MAX2(ctx->Const.MaxCombinedTextureImageUnits,
+ ctx->Const.MaxTextureCoordUnits);
+
+ ASSERT(k <= Elements(ctx->Texture.Unit));
+
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glActiveTexture %s\n",
_mesa_lookup_enum_by_nr(texture));
- if (texUnit >= ctx->Const.MaxTextureImageUnits) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture)");
+ if (texUnit >= k) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture=%s)",
+ _mesa_lookup_enum_by_nr(texture));
return;
}
/* update current stack pointer */
ctx->CurrentStack = &ctx->TextureMatrixStack[texUnit];
}
-
- if (ctx->Driver.ActiveTexture) {
- (*ctx->Driver.ActiveTexture)( ctx, (GLuint) texUnit );
- }
}
GLuint texUnit = texture - GL_TEXTURE0;
ASSERT_OUTSIDE_BEGIN_END(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glClientActiveTexture %s\n",
+ _mesa_lookup_enum_by_nr(texture));
+
if (texUnit >= ctx->Const.MaxTextureCoordUnits) {
_mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)");
return;
}
+ if (ctx->Array.ActiveTexture == texUnit)
+ return;
+
FLUSH_VERTICES(ctx, _NEW_ARRAY);
ctx->Array.ActiveTexture = texUnit;
}
ctx->Texture._TexMatEnabled = 0x0;
for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) {
+ ASSERT(u < Elements(ctx->TextureMatrixStack));
if (_math_matrix_is_dirty(ctx->TextureMatrixStack[u].Top)) {
_math_matrix_analyse( ctx->TextureMatrixStack[u].Top );
if (ctx->Texture.Unit[u]._ReallyEnabled &&
ctx->TextureMatrixStack[u].Top->type != MATRIX_IDENTITY)
ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(u);
-
- if (ctx->Driver.TextureMatrix)
- ctx->Driver.TextureMatrix( ctx, u, ctx->TextureMatrixStack[u].Top);
}
}
}
/*
* Update texture unit state.
*/
- for (unit = 0; unit < ctx->Const.MaxTextureImageUnits; unit++) {
+ for (unit = 0; unit < ctx->Const.MaxCombinedTextureImageUnits; unit++) {
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLbitfield enabledVertTargets = 0x0;
GLbitfield enabledFragTargets = 0x0;
ctx->Texture._GenFlags |= texUnit->_GenFlags;
}
+ ASSERT(unit < Elements(ctx->TextureMatrixStack));
if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY)
ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
}
ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
+
/* no mention of this in spec, but maybe id matrix expected? */
ASSIGN_4V( texUnit->RotMatrix, 1.0, 0.0, 0.0, 1.0 );
ctx->Texture.CurrentUnit = 0; /* multitexture */
ctx->Texture._EnabledUnits = 0x0;
ctx->Texture.SharedPalette = GL_FALSE;
-#if FEATURE_colortable
_mesa_init_colortable(&ctx->Texture.Palette);
-#endif
- for (u = 0; u < MAX_TEXTURE_UNITS; u++)
+ for (u = 0; u < Elements(ctx->Texture.Unit); u++)
init_texture_unit(ctx, u);
/* After we're done initializing the context's texture state the default
- * texture objects' refcounts should be at least MAX_TEXTURE_UNITS + 1.
+ * texture objects' refcounts should be at least
+ * MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1.
*/
assert(ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount
- >= MAX_TEXTURE_UNITS + 1);
+ >= MAX_COMBINED_TEXTURE_IMAGE_UNITS + 1);
/* Allocate proxy textures */
if (!alloc_proxy_textures( ctx ))
GLuint u, tgt;
/* unreference current textures */
- for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
+ for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
/* The _Current texture could account for another reference */
_mesa_reference_texobj(&ctx->Texture.Unit[u]._Current, NULL);
for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
-#if FEATURE_colortable
- for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++)
+ for (u = 0; u < Elements(ctx->Texture.Unit); u++)
_mesa_free_colortable_data(&ctx->Texture.Unit[u].ColorTable);
-#endif
}
{
GLuint u, tex;
- for (u = 0; u < MAX_TEXTURE_UNITS; u++) {
+ for (u = 0; u < Elements(ctx->Texture.Unit); u++) {
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u];
for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
_mesa_reference_texobj(&texUnit->CurrentTex[tex],