X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Ftexstate.c;h=0687e5760c9b96303f22cf726c6da41880e95a7b;hb=6340d6bf22ad0bfedf8565500336237a8da887f5;hp=2c1d155f52ece56e98515e316b81353a0ce42f81;hpb=781fb93877ea3a6faeefcdb48d9b463da7d954a3;p=mesa.git diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 2c1d155f52e..0687e5760c9 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 5.1 + * Version: 6.5.1 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -22,36 +22,78 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/** + * \file texstate.c + * + * Texture state handling. + */ #include "glheader.h" #include "colormac.h" #include "colortab.h" #include "context.h" #include "enums.h" -#include "extensions.h" #include "macros.h" -#include "nvfragprog.h" +#include "texcompress.h" #include "texobj.h" #include "teximage.h" #include "texstate.h" +#include "texenvprogram.h" #include "mtypes.h" #include "math/m_xform.h" -#include "math/m_matrix.h" +#include "shaderobjects.h" -#ifdef SPECIALCAST -/* Needed for an Amiga compiler */ #define ENUM_TO_FLOAT(X) ((GLfloat)(GLint)(X)) #define ENUM_TO_DOUBLE(X) ((GLdouble)(GLint)(X)) -#else -/* all other compilers */ -#define ENUM_TO_FLOAT(X) ((GLfloat)(X)) -#define ENUM_TO_DOUBLE(X) ((GLdouble)(X)) -#endif +/** + * Default texture combine environment state. This is used to initialize + * a context's texture units and as the basis for converting "classic" + * texture environmnets to ARB_texture_env_combine style values. + */ +static const struct gl_tex_env_combine_state default_combine_state = { + GL_MODULATE, GL_MODULATE, + { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT }, + { GL_TEXTURE, GL_PREVIOUS, GL_CONSTANT }, + { GL_SRC_COLOR, GL_SRC_COLOR, GL_SRC_ALPHA }, + { GL_SRC_ALPHA, GL_SRC_ALPHA, GL_SRC_ALPHA }, + 0, 0, + 2, 2 +}; + + +/** + * Copy a texture binding. Helper used by _mesa_copy_texture_state(). + */ +static void +copy_texture_binding(const GLcontext *ctx, + struct gl_texture_object **dst, + struct gl_texture_object *src) +{ + /* only copy if names differ (per OpenGL SI) */ + if ((*dst)->Name != src->Name) { + /* unbind/delete dest binding which we're changing */ + (*dst)->RefCount--; + if ((*dst)->RefCount == 0) { + /* time to delete this texture object */ + ASSERT((*dst)->Name != 0); + ASSERT(ctx->Driver.DeleteTexture); + /* XXX cast-away const, unfortunately */ + (*ctx->Driver.DeleteTexture)((GLcontext *) ctx, *dst); + } + /* make new binding, incrementing ref count */ + *dst = src; + src->RefCount++; + } +} + +/** + * Used by glXCopyContext to copy texture state from one context to another. + */ void _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) { @@ -92,26 +134,26 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ) dst->Texture.Unit[i].LodBias = src->Texture.Unit[i].LodBias; /* GL_EXT_texture_env_combine */ - dst->Texture.Unit[i].CombineModeRGB = src->Texture.Unit[i].CombineModeRGB; - dst->Texture.Unit[i].CombineModeA = src->Texture.Unit[i].CombineModeA; - COPY_3V(dst->Texture.Unit[i].CombineSourceRGB, src->Texture.Unit[i].CombineSourceRGB); - COPY_3V(dst->Texture.Unit[i].CombineSourceA, src->Texture.Unit[i].CombineSourceA); - COPY_3V(dst->Texture.Unit[i].CombineOperandRGB, src->Texture.Unit[i].CombineOperandRGB); - COPY_3V(dst->Texture.Unit[i].CombineOperandA, src->Texture.Unit[i].CombineOperandA); - dst->Texture.Unit[i].CombineScaleShiftRGB = src->Texture.Unit[i].CombineScaleShiftRGB; - dst->Texture.Unit[i].CombineScaleShiftA = src->Texture.Unit[i].CombineScaleShiftA; - - /* texture object state */ - _mesa_copy_texture_object(dst->Texture.Unit[i].Current1D, - src->Texture.Unit[i].Current1D); - _mesa_copy_texture_object(dst->Texture.Unit[i].Current2D, - src->Texture.Unit[i].Current2D); - _mesa_copy_texture_object(dst->Texture.Unit[i].Current3D, - src->Texture.Unit[i].Current3D); - _mesa_copy_texture_object(dst->Texture.Unit[i].CurrentCubeMap, - src->Texture.Unit[i].CurrentCubeMap); - _mesa_copy_texture_object(dst->Texture.Unit[i].CurrentRect, - src->Texture.Unit[i].CurrentRect); + dst->Texture.Unit[i].Combine.ModeRGB = src->Texture.Unit[i].Combine.ModeRGB; + dst->Texture.Unit[i].Combine.ModeA = src->Texture.Unit[i].Combine.ModeA; + COPY_3V(dst->Texture.Unit[i].Combine.SourceRGB, src->Texture.Unit[i].Combine.SourceRGB); + COPY_3V(dst->Texture.Unit[i].Combine.SourceA, src->Texture.Unit[i].Combine.SourceA); + COPY_3V(dst->Texture.Unit[i].Combine.OperandRGB, src->Texture.Unit[i].Combine.OperandRGB); + COPY_3V(dst->Texture.Unit[i].Combine.OperandA, src->Texture.Unit[i].Combine.OperandA); + dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB; + dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA; + + /* copy texture object bindings, not contents of texture objects */ + copy_texture_binding(src, &dst->Texture.Unit[i].Current1D, + src->Texture.Unit[i].Current1D); + copy_texture_binding(src, &dst->Texture.Unit[i].Current2D, + src->Texture.Unit[i].Current2D); + copy_texture_binding(src, &dst->Texture.Unit[i].Current3D, + src->Texture.Unit[i].Current3D); + copy_texture_binding(src, &dst->Texture.Unit[i].CurrentCubeMap, + src->Texture.Unit[i].CurrentCubeMap); + copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect, + src->Texture.Unit[i].CurrentRect); } } @@ -125,22 +167,22 @@ _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->CombineModeRGB)); - _mesa_printf(" GL_COMBINE_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineModeA)); - _mesa_printf(" GL_SOURCE0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceRGB[0])); - _mesa_printf(" GL_SOURCE1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceRGB[1])); - _mesa_printf(" GL_SOURCE2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceRGB[2])); - _mesa_printf(" GL_SOURCE0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceA[0])); - _mesa_printf(" GL_SOURCE1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceA[1])); - _mesa_printf(" GL_SOURCE2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineSourceA[2])); - _mesa_printf(" GL_OPERAND0_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandRGB[0])); - _mesa_printf(" GL_OPERAND1_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandRGB[1])); - _mesa_printf(" GL_OPERAND2_RGB = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandRGB[2])); - _mesa_printf(" GL_OPERAND0_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandA[0])); - _mesa_printf(" GL_OPERAND1_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandA[1])); - _mesa_printf(" GL_OPERAND2_ALPHA = %s\n", _mesa_lookup_enum_by_nr(texUnit->CombineOperandA[2])); - _mesa_printf(" GL_RGB_SCALE = %d\n", 1 << texUnit->CombineScaleShiftRGB); - _mesa_printf(" GL_ALPHA_SCALE = %d\n", 1 << texUnit->CombineScaleShiftA); + _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]); } @@ -150,14 +192,141 @@ _mesa_print_texunit_state( GLcontext *ctx, GLuint unit ) /* Texture Environment */ /**********************************************************************/ +/** + * Convert "classic" texture environment to ARB_texture_env_combine style + * environments. + * + * \param state texture_env_combine state vector to be filled-in. + * \param mode Classic texture environment mode (i.e., \c GL_REPLACE, + * \c GL_BLEND, \c GL_DECAL, etc.). + * \param texBaseFormat Base format of the texture associated with the + * texture unit. + */ +static void +calculate_derived_texenv( struct gl_tex_env_combine_state *state, + GLenum mode, GLenum texBaseFormat ) +{ + GLenum mode_rgb; + GLenum mode_a; -void + *state = default_combine_state; + + switch (texBaseFormat) { + case GL_ALPHA: + state->SourceRGB[0] = GL_PREVIOUS; + break; + + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + case GL_RGBA: + break; + + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + state->SourceA[0] = GL_PREVIOUS; + break; + + default: + _mesa_problem(NULL, "Invalid texBaseFormat in calculate_derived_texenv"); + return; + } + + switch (mode) { + case GL_REPLACE: + case GL_MODULATE: + mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode; + mode_a = mode; + break; + + case GL_DECAL: + mode_rgb = GL_INTERPOLATE; + mode_a = GL_REPLACE; + + state->SourceA[0] = GL_PREVIOUS; + + /* Having alpha / luminance / intensity textures replace using the + * incoming fragment color matches the definition in NV_texture_shader. + * The 1.5 spec simply marks these as "undefined". + */ + switch (texBaseFormat) { + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + state->SourceRGB[0] = GL_PREVIOUS; + break; + case GL_RGB: + case GL_YCBCR_MESA: + mode_rgb = GL_REPLACE; + break; + case GL_RGBA: + state->SourceRGB[2] = GL_TEXTURE; + break; + } + break; + + case GL_BLEND: + mode_rgb = GL_INTERPOLATE; + mode_a = GL_MODULATE; + + switch (texBaseFormat) { + case GL_ALPHA: + mode_rgb = GL_REPLACE; + break; + case GL_INTENSITY: + mode_a = GL_INTERPOLATE; + state->SourceA[0] = GL_CONSTANT; + state->OperandA[2] = GL_SRC_ALPHA; + /* FALLTHROUGH */ + case GL_LUMINANCE: + case GL_RGB: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + case GL_YCBCR_MESA: + state->SourceRGB[2] = GL_TEXTURE; + state->SourceA[2] = GL_TEXTURE; + state->SourceRGB[0] = GL_CONSTANT; + state->OperandRGB[2] = GL_SRC_COLOR; + break; + } + break; + + case GL_ADD: + mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD; + mode_a = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE; + break; + + default: + _mesa_problem(NULL, + "Invalid texture env mode in calculate_derived_texenv"); + return; + } + + state->ModeRGB = (state->SourceRGB[0] != GL_PREVIOUS) + ? mode_rgb : GL_REPLACE; + state->ModeA = (state->SourceA[0] != GL_PREVIOUS) + ? mode_a : GL_REPLACE; +} + + +void GLAPIENTRY _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) { + GLuint maxUnit; GET_CURRENT_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_unit *texUnit; ASSERT_OUTSIDE_BEGIN_END(ctx); + maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) + ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits; + if (ctx->Texture.CurrentUnit >= maxUnit) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexEnvfv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + #define TE_ERROR(errCode, msg, value) \ _mesa_error(ctx, errCode, msg, _mesa_lookup_enum_by_nr(value)); @@ -166,6 +335,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) case GL_TEXTURE_ENV_MODE: { const GLenum mode = (GLenum) (GLint) *param; + if (texUnit->EnvMode == mode) + return; if (mode == GL_MODULATE || mode == GL_BLEND || mode == GL_DECAL || @@ -175,8 +346,6 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine))) { /* legal */ - if (texUnit->EnvMode == mode) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); texUnit->EnvMode = mode; } @@ -203,6 +372,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum mode = (GLenum) (GLint) *param; + if (texUnit->Combine.ModeRGB == mode) + return; switch (mode) { case GL_REPLACE: case GL_MODULATE: @@ -243,10 +414,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } - if (texUnit->CombineModeRGB == mode) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineModeRGB = mode; + texUnit->Combine.ModeRGB = mode; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); @@ -257,6 +426,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum mode = (GLenum) (GLint) *param; + if (texUnit->Combine.ModeA == mode) + return; switch (mode) { case GL_REPLACE: case GL_MODULATE: @@ -283,11 +454,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode); return; } - - if (texUnit->CombineModeA == mode) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineModeA = mode; + texUnit->Combine.ModeA = mode; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); @@ -301,6 +469,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) ctx->Extensions.ARB_texture_env_combine) { const GLenum source = (GLenum) (GLint) *param; const GLuint s = pname - GL_SOURCE0_RGB; + if (texUnit->Combine.SourceRGB[s] == source) + return; if (source == GL_TEXTURE || source == GL_CONSTANT || source == GL_PRIMARY_COLOR || @@ -311,10 +481,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) (ctx->Extensions.ATI_texture_env_combine3 && (source == GL_ZERO || source == GL_ONE))) { /* legal */ - if (texUnit->CombineSourceRGB[s] == source) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineSourceRGB[s] = source; + texUnit->Combine.SourceRGB[s] = source; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source); @@ -333,6 +501,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) ctx->Extensions.ARB_texture_env_combine) { const GLenum source = (GLenum) (GLint) *param; const GLuint s = pname - GL_SOURCE0_ALPHA; + if (texUnit->Combine.SourceA[s] == source) + return; if (source == GL_TEXTURE || source == GL_CONSTANT || source == GL_PRIMARY_COLOR || @@ -343,10 +513,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) (ctx->Extensions.ATI_texture_env_combine3 && (source == GL_ZERO || source == GL_ONE))) { /* legal */ - if (texUnit->CombineSourceA[s] == source) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineSourceA[s] = source; + texUnit->Combine.SourceA[s] = source; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source); @@ -364,15 +532,15 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) ctx->Extensions.ARB_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; const GLuint s = pname - GL_OPERAND0_RGB; + if (texUnit->Combine.OperandRGB[s] == operand) + return; switch (operand) { case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: - if (texUnit->CombineOperandRGB[s] == operand) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineOperandRGB[s] = operand; + texUnit->Combine.OperandRGB[s] = operand; break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); @@ -389,14 +557,13 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; + if (texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] == operand) + return; switch (operand) { case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: - if (texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA] == - operand) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineOperandA[pname-GL_OPERAND0_ALPHA] = operand; + texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand; break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); @@ -409,46 +576,66 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) } break; case GL_OPERAND2_RGB: - if (ctx->Extensions.EXT_texture_env_combine || - ctx->Extensions.ARB_texture_env_combine) { + if (ctx->Extensions.ARB_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; + if (texUnit->Combine.OperandRGB[2] == operand) + return; switch (operand) { case GL_SRC_COLOR: /* ARB combine only */ case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */ case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */ - if (texUnit->CombineOperandRGB[2] == operand) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineOperandRGB[2] = operand; + texUnit->Combine.OperandRGB[2] = operand; break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); return; } } + else if (ctx->Extensions.EXT_texture_env_combine) { + const GLenum operand = (GLenum) (GLint) *param; + if (texUnit->Combine.OperandRGB[2] == operand) + return; + /* operand must be GL_SRC_ALPHA which is the initial value - thus + don't need to actually compare the operand to the possible value */ + else { + TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); + return; + } + } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; } break; case GL_OPERAND2_ALPHA: - if (ctx->Extensions.EXT_texture_env_combine || - ctx->Extensions.ARB_texture_env_combine) { + if (ctx->Extensions.ARB_texture_env_combine) { const GLenum operand = (GLenum) (GLint) *param; + if (texUnit->Combine.OperandA[2] == operand) + return; switch (operand) { case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */ - if (texUnit->CombineOperandA[2] == operand) - return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineOperandA[2] = operand; + texUnit->Combine.OperandA[2] = operand; break; default: TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); return; } } + else if (ctx->Extensions.EXT_texture_env_combine) { + const GLenum operand = (GLenum) (GLint) *param; + if (texUnit->Combine.OperandA[2] == operand) + return; + /* operand must be GL_SRC_ALPHA which is the initial value - thus + don't need to actually compare the operand to the possible value */ + else { + TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", operand); + return; + } + } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); return; @@ -472,10 +659,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) "glTexEnv(GL_RGB_SCALE not 1, 2 or 4)" ); return; } - if (texUnit->CombineScaleShiftRGB == newshift) + if (texUnit->Combine.ScaleShiftRGB == newshift) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineScaleShiftRGB = newshift; + texUnit->Combine.ScaleShiftRGB = newshift; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); @@ -500,10 +687,10 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) "glTexEnv(GL_ALPHA_SCALE not 1, 2 or 4)" ); return; } - if (texUnit->CombineScaleShiftA == newshift) + if (texUnit->Combine.ScaleShiftA == newshift) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->CombineScaleShiftA = newshift; + texUnit->Combine.ScaleShiftA = newshift; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); @@ -525,8 +712,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) if (texUnit->LodBias == param[0]) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->LodBias = CLAMP(param[0], -ctx->Const.MaxTextureLodBias, - ctx->Const.MaxTextureLodBias); + texUnit->LodBias = param[0]; } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); @@ -581,7 +767,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) } -void +void GLAPIENTRY _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ) { _mesa_TexEnvfv( target, pname, ¶m ); @@ -589,7 +775,7 @@ _mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ) -void +void GLAPIENTRY _mesa_TexEnvi( GLenum target, GLenum pname, GLint param ) { GLfloat p[4]; @@ -599,7 +785,7 @@ _mesa_TexEnvi( GLenum target, GLenum pname, GLint param ) } -void +void GLAPIENTRY _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ) { GLfloat p[4]; @@ -617,13 +803,23 @@ _mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ) } -void +void GLAPIENTRY _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) { + GLuint maxUnit; + const struct gl_texture_unit *texUnit; GET_CURRENT_CONTEXT(ctx); - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; ASSERT_OUTSIDE_BEGIN_END(ctx); + maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) + ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits; + if (ctx->Texture.CurrentUnit >= maxUnit) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnvfv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + if (target == GL_TEXTURE_ENV) { switch (pname) { case GL_TEXTURE_ENV_MODE: @@ -635,7 +831,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_COMBINE_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineModeRGB; + *params = (GLfloat) texUnit->Combine.ModeRGB; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -644,7 +840,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_COMBINE_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineModeA; + *params = (GLfloat) texUnit->Combine.ModeA; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -653,7 +849,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_SOURCE0_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineSourceRGB[0]; + *params = (GLfloat) texUnit->Combine.SourceRGB[0]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -662,7 +858,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_SOURCE1_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineSourceRGB[1]; + *params = (GLfloat) texUnit->Combine.SourceRGB[1]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -671,7 +867,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_SOURCE2_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineSourceRGB[2]; + *params = (GLfloat) texUnit->Combine.SourceRGB[2]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -680,7 +876,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_SOURCE0_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineSourceA[0]; + *params = (GLfloat) texUnit->Combine.SourceA[0]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -689,7 +885,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_SOURCE1_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineSourceA[1]; + *params = (GLfloat) texUnit->Combine.SourceA[1]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -698,7 +894,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_SOURCE2_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineSourceA[2]; + *params = (GLfloat) texUnit->Combine.SourceA[2]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -707,7 +903,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_OPERAND0_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineOperandRGB[0]; + *params = (GLfloat) texUnit->Combine.OperandRGB[0]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -716,7 +912,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_OPERAND1_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineOperandRGB[1]; + *params = (GLfloat) texUnit->Combine.OperandRGB[1]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -725,7 +921,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_OPERAND2_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineOperandRGB[2]; + *params = (GLfloat) texUnit->Combine.OperandRGB[2]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -734,7 +930,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_OPERAND0_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineOperandA[0]; + *params = (GLfloat) texUnit->Combine.OperandA[0]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -743,7 +939,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_OPERAND1_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineOperandA[1]; + *params = (GLfloat) texUnit->Combine.OperandA[1]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -752,7 +948,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_OPERAND2_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLfloat) texUnit->CombineOperandA[2]; + *params = (GLfloat) texUnit->Combine.OperandA[2]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnvfv(pname)"); @@ -761,9 +957,9 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_RGB_SCALE: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - if (texUnit->CombineScaleShiftRGB == 0) + if (texUnit->Combine.ScaleShiftRGB == 0) *params = 1.0; - else if (texUnit->CombineScaleShiftRGB == 1) + else if (texUnit->Combine.ScaleShiftRGB == 1) *params = 2.0; else *params = 4.0; @@ -776,9 +972,9 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) case GL_ALPHA_SCALE: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - if (texUnit->CombineScaleShiftA == 0) + if (texUnit->Combine.ScaleShiftA == 0) *params = 1.0; - else if (texUnit->CombineScaleShiftA == 1) + else if (texUnit->Combine.ScaleShiftA == 1) *params = 2.0; else *params = 4.0; @@ -828,13 +1024,23 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ) } -void +void GLAPIENTRY _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) { + GLuint maxUnit; + const struct gl_texture_unit *texUnit; GET_CURRENT_CONTEXT(ctx); - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; ASSERT_OUTSIDE_BEGIN_END(ctx); + maxUnit = (target == GL_POINT_SPRITE_NV && pname == GL_COORD_REPLACE_NV) + ? ctx->Const.MaxTextureCoordUnits : ctx->Const.MaxTextureImageUnits; + if (ctx->Texture.CurrentUnit >= maxUnit) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexEnviv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + if (target == GL_TEXTURE_ENV) { switch (pname) { case GL_TEXTURE_ENV_MODE: @@ -849,7 +1055,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_COMBINE_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineModeRGB; + *params = (GLint) texUnit->Combine.ModeRGB; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -858,7 +1064,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_COMBINE_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineModeA; + *params = (GLint) texUnit->Combine.ModeA; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -867,7 +1073,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_SOURCE0_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineSourceRGB[0]; + *params = (GLint) texUnit->Combine.SourceRGB[0]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -876,7 +1082,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_SOURCE1_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineSourceRGB[1]; + *params = (GLint) texUnit->Combine.SourceRGB[1]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -885,7 +1091,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_SOURCE2_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineSourceRGB[2]; + *params = (GLint) texUnit->Combine.SourceRGB[2]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -894,7 +1100,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_SOURCE0_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineSourceA[0]; + *params = (GLint) texUnit->Combine.SourceA[0]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -903,7 +1109,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_SOURCE1_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineSourceA[1]; + *params = (GLint) texUnit->Combine.SourceA[1]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -912,7 +1118,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_SOURCE2_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineSourceA[2]; + *params = (GLint) texUnit->Combine.SourceA[2]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -921,7 +1127,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_OPERAND0_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineOperandRGB[0]; + *params = (GLint) texUnit->Combine.OperandRGB[0]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -930,7 +1136,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_OPERAND1_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineOperandRGB[1]; + *params = (GLint) texUnit->Combine.OperandRGB[1]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -939,7 +1145,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_OPERAND2_RGB: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineOperandRGB[2]; + *params = (GLint) texUnit->Combine.OperandRGB[2]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -948,7 +1154,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_OPERAND0_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineOperandA[0]; + *params = (GLint) texUnit->Combine.OperandA[0]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -957,7 +1163,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_OPERAND1_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineOperandA[1]; + *params = (GLint) texUnit->Combine.OperandA[1]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -966,7 +1172,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_OPERAND2_ALPHA: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - *params = (GLint) texUnit->CombineOperandA[2]; + *params = (GLint) texUnit->Combine.OperandA[2]; } else { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexEnviv(pname)"); @@ -975,9 +1181,9 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_RGB_SCALE: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - if (texUnit->CombineScaleShiftRGB == 0) + if (texUnit->Combine.ScaleShiftRGB == 0) *params = 1; - else if (texUnit->CombineScaleShiftRGB == 1) + else if (texUnit->Combine.ScaleShiftRGB == 1) *params = 2; else *params = 4; @@ -990,9 +1196,9 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) case GL_ALPHA_SCALE: if (ctx->Extensions.EXT_texture_env_combine || ctx->Extensions.ARB_texture_env_combine) { - if (texUnit->CombineScaleShiftA == 0) + if (texUnit->Combine.ScaleShiftA == 0) *params = 1; - else if (texUnit->CombineScaleShiftA == 1) + else if (texUnit->Combine.ScaleShiftA == 1) *params = 2; else *params = 4; @@ -1049,21 +1255,50 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ) /* Texture Parameters */ /**********************************************************************/ +static GLboolean +_mesa_validate_texture_wrap_mode(GLcontext * ctx, + GLenum target, GLenum eparam) +{ + const struct gl_extensions * const e = & ctx->Extensions; -void + if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE || + (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) { + /* any texture target */ + return GL_TRUE; + } + else if (target != GL_TEXTURE_RECTANGLE_NV && + (eparam == GL_REPEAT || + (eparam == GL_MIRRORED_REPEAT && + e->ARB_texture_mirrored_repeat) || + (eparam == GL_MIRROR_CLAMP_EXT && + (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) || + (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT && + (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) || + (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT && + (e->EXT_texture_mirror_clamp)))) { + /* non-rectangle texture */ + return GL_TRUE; + } + + _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return GL_FALSE; +} + + +void GLAPIENTRY _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param ) { _mesa_TexParameterfv(target, pname, ¶m); } -void +void GLAPIENTRY _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) { - GET_CURRENT_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - GLenum eparam = (GLenum) (GLint) params[0]; + const GLenum eparam = (GLenum) (GLint) params[0]; + struct gl_texture_unit *texUnit; struct gl_texture_object *texObj; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) @@ -1073,6 +1308,12 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) *params, _mesa_lookup_enum_by_nr(eparam)); + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexParameterfv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; switch (target) { case GL_TEXTURE_1D: @@ -1142,81 +1383,34 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) case GL_TEXTURE_WRAP_S: if (texObj->WrapS == eparam) return; - if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE || - (eparam == GL_CLAMP_TO_BORDER && - ctx->Extensions.ARB_texture_border_clamp)) { - /* any texture target */ - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->WrapS = eparam; - } - else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && - (eparam == GL_REPEAT || - (eparam == GL_MIRRORED_REPEAT && - ctx->Extensions.ARB_texture_mirrored_repeat) || - (eparam == GL_MIRROR_CLAMP_ATI && - ctx->Extensions.ATI_texture_mirror_once) || - (eparam == GL_MIRROR_CLAMP_TO_EDGE_ATI && - ctx->Extensions.ATI_texture_mirror_once))) { - /* non-rectangle texture */ + if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); texObj->WrapS = eparam; } else { - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); return; } break; case GL_TEXTURE_WRAP_T: if (texObj->WrapT == eparam) return; - if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE || - (eparam == GL_CLAMP_TO_BORDER && - ctx->Extensions.ARB_texture_border_clamp)) { - /* any texture target */ - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->WrapT = eparam; - } - else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && - (eparam == GL_REPEAT || - (eparam == GL_MIRRORED_REPEAT && - ctx->Extensions.ARB_texture_mirrored_repeat) || - (eparam == GL_MIRROR_CLAMP_ATI && - ctx->Extensions.ATI_texture_mirror_once) || - (eparam == GL_MIRROR_CLAMP_TO_EDGE_ATI && - ctx->Extensions.ATI_texture_mirror_once))) { - /* non-rectangle texture */ + if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); texObj->WrapT = eparam; } else { - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); return; } break; case GL_TEXTURE_WRAP_R: if (texObj->WrapR == eparam) return; - if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE || - (eparam == GL_CLAMP_TO_BORDER && - ctx->Extensions.ARB_texture_border_clamp)) { - /* any texture target */ - FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->WrapR = eparam; - } - else if (texObj->Target != GL_TEXTURE_RECTANGLE_NV && - (eparam == GL_REPEAT || - (eparam == GL_MIRRORED_REPEAT && - ctx->Extensions.ARB_texture_mirrored_repeat) || - (eparam == GL_MIRROR_CLAMP_ATI && - ctx->Extensions.ATI_texture_mirror_once) || - (eparam == GL_MIRROR_CLAMP_TO_EDGE_ATI && - ctx->Extensions.ATI_texture_mirror_once))) { - /* non-rectangle texture */ + if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); texObj->WrapR = eparam; } else { - _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param)" ); + return; } break; case GL_TEXTURE_BORDER_COLOR: @@ -1273,7 +1467,9 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) return; } FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texObj->MaxAnisotropy = params[0]; + /* clamp to max, that's what NVIDIA does */ + texObj->MaxAnisotropy = MIN2(params[0], + ctx->Const.MaxTextureMaxAnisotropy); } else { _mesa_error(ctx, GL_INVALID_ENUM, @@ -1402,9 +1598,10 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) case GL_TEXTURE_LOD_BIAS: /* NOTE: this is really part of OpenGL 1.4, not EXT_texture_lod_bias*/ if (ctx->Extensions.EXT_texture_lod_bias) { - texObj->LodBias = CLAMP(params[0], - -ctx->Const.MaxTextureLodBias, - ctx->Const.MaxTextureLodBias); + if (texObj->LodBias != params[0]) { + FLUSH_VERTICES(ctx, _NEW_TEXTURE); + texObj->LodBias = params[0]; + } } break; @@ -1422,7 +1619,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) } -void +void GLAPIENTRY _mesa_TexParameteri( GLenum target, GLenum pname, GLint param ) { GLfloat fparam[4]; @@ -1435,7 +1632,7 @@ _mesa_TexParameteri( GLenum target, GLenum pname, GLint param ) } -void +void GLAPIENTRY _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ) { GLfloat fparam[4]; @@ -1456,7 +1653,7 @@ _mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ) } -void +void GLAPIENTRY _mesa_GetTexLevelParameterfv( GLenum target, GLint level, GLenum pname, GLfloat *params ) { @@ -1498,18 +1695,26 @@ tex_image_dimensions(GLcontext *ctx, GLenum target) } -void +void GLAPIENTRY _mesa_GetTexLevelParameteriv( GLenum target, GLint level, GLenum pname, GLint *params ) { - GET_CURRENT_CONTEXT(ctx); - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const struct gl_texture_unit *texUnit; const struct gl_texture_image *img = NULL; GLuint dimensions; GLboolean isProxy; GLint maxLevels; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexLevelParameteriv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + /* this will catch bad target values */ dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */ if (dimensions == 0) { @@ -1517,32 +1722,10 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, return; } - switch (target) { - case GL_TEXTURE_1D: - case GL_PROXY_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_PROXY_TEXTURE_2D: - maxLevels = ctx->Const.MaxTextureLevels; - break; - case GL_TEXTURE_3D: - case GL_PROXY_TEXTURE_3D: - maxLevels = ctx->Const.Max3DTextureLevels; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - case GL_PROXY_TEXTURE_CUBE_MAP: - maxLevels = ctx->Const.MaxCubeTextureLevels; - break; - case GL_TEXTURE_RECTANGLE_NV: - case GL_PROXY_TEXTURE_RECTANGLE_NV: - maxLevels = 1; - break; - default: - _mesa_problem(ctx, "switch in _mesa_GetTexLevelParameter"); + maxLevels = _mesa_max_texture_levels(ctx, target); + if (maxLevels == 0) { + /* should not happen since was just checked above */ + _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter"); return; } @@ -1561,11 +1744,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, return; } - isProxy = (target == GL_PROXY_TEXTURE_1D) || - (target == GL_PROXY_TEXTURE_2D) || - (target == GL_PROXY_TEXTURE_3D) || - (target == GL_PROXY_TEXTURE_CUBE_MAP) || - (target == GL_PROXY_TEXTURE_RECTANGLE_NV); + isProxy = _mesa_is_proxy_texture(target); switch (pname) { case GL_TEXTURE_WIDTH: @@ -1578,38 +1757,39 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = img->Depth; return; case GL_TEXTURE_INTERNAL_FORMAT: - *params = img->IntFormat; + *params = img->InternalFormat; return; case GL_TEXTURE_BORDER: *params = img->Border; return; case GL_TEXTURE_RED_SIZE: - if (img->Format == GL_RGB || img->Format == GL_RGBA) + if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->RedBits; else *params = 0; return; case GL_TEXTURE_GREEN_SIZE: - if (img->Format == GL_RGB || img->Format == GL_RGBA) + if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->GreenBits; else *params = 0; return; case GL_TEXTURE_BLUE_SIZE: - if (img->Format == GL_RGB || img->Format == GL_RGBA) + if (img->_BaseFormat == GL_RGB || img->_BaseFormat == GL_RGBA) *params = img->TexFormat->BlueBits; else *params = 0; return; case GL_TEXTURE_ALPHA_SIZE: - if (img->Format == GL_ALPHA || img->Format == GL_LUMINANCE_ALPHA || - img->Format == GL_RGBA) + if (img->_BaseFormat == GL_ALPHA || + img->_BaseFormat == GL_LUMINANCE_ALPHA || + img->_BaseFormat == GL_RGBA) *params = img->TexFormat->AlphaBits; else *params = 0; return; case GL_TEXTURE_INTENSITY_SIZE: - if (img->Format != GL_INTENSITY) + if (img->_BaseFormat != GL_INTENSITY) *params = 0; else if (img->TexFormat->IntensityBits > 0) *params = img->TexFormat->IntensityBits; @@ -1617,8 +1797,8 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); return; case GL_TEXTURE_LUMINANCE_SIZE: - if (img->Format != GL_LUMINANCE && - img->Format != GL_LUMINANCE_ALPHA) + if (img->_BaseFormat != GL_LUMINANCE && + img->_BaseFormat != GL_LUMINANCE_ALPHA) *params = 0; else if (img->TexFormat->LuminanceBits > 0) *params = img->TexFormat->LuminanceBits; @@ -1626,30 +1806,44 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = MIN2(img->TexFormat->RedBits, img->TexFormat->GreenBits); return; case GL_TEXTURE_INDEX_SIZE_EXT: - if (img->Format == GL_COLOR_INDEX) + if (img->_BaseFormat == GL_COLOR_INDEX) *params = img->TexFormat->IndexBits; else *params = 0; return; - case GL_DEPTH_BITS: - /* XXX this isn't in the GL_SGIX_depth_texture spec - * but seems appropriate. - */ - if (ctx->Extensions.SGIX_depth_texture) + case GL_TEXTURE_DEPTH_SIZE_ARB: + if (ctx->Extensions.SGIX_depth_texture || + ctx->Extensions.ARB_depth_texture) *params = img->TexFormat->DepthBits; else _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); return; + case GL_TEXTURE_STENCIL_SIZE_EXT: + if (ctx->Extensions.EXT_packed_depth_stencil) { + *params = img->TexFormat->StencilBits; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); + } + return; /* GL_ARB_texture_compression */ case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: if (ctx->Extensions.ARB_texture_compression) { - if (img->IsCompressed && !isProxy) - *params = img->CompressedSize; - else + if (img->IsCompressed && !isProxy) { + /* Don't use ctx->Driver.CompressedTextureSize() since that + * may returned a padded hardware size. + */ + *params = _mesa_compressed_texture_size(ctx, img->Width, + img->Height, img->Depth, + img->TexFormat->MesaFormat); + } + else { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexLevelParameter[if]v(pname)"); + } } else { _mesa_error(ctx, GL_INVALID_ENUM, @@ -1666,6 +1860,71 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, } return; + /* GL_ARB_texture_float */ + case GL_TEXTURE_RED_TYPE_ARB: + if (ctx->Extensions.ARB_texture_float) { + *params = img->TexFormat->RedBits ? img->TexFormat->DataType : GL_NONE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); + } + return; + case GL_TEXTURE_GREEN_TYPE_ARB: + if (ctx->Extensions.ARB_texture_float) { + *params = img->TexFormat->GreenBits ? img->TexFormat->DataType : GL_NONE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); + } + return; + case GL_TEXTURE_BLUE_TYPE_ARB: + if (ctx->Extensions.ARB_texture_float) { + *params = img->TexFormat->BlueBits ? img->TexFormat->DataType : GL_NONE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); + } + return; + case GL_TEXTURE_ALPHA_TYPE_ARB: + if (ctx->Extensions.ARB_texture_float) { + *params = img->TexFormat->AlphaBits ? img->TexFormat->DataType : GL_NONE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); + } + return; + case GL_TEXTURE_LUMINANCE_TYPE_ARB: + if (ctx->Extensions.ARB_texture_float) { + *params = img->TexFormat->LuminanceBits ? img->TexFormat->DataType : GL_NONE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); + } + return; + case GL_TEXTURE_INTENSITY_TYPE_ARB: + if (ctx->Extensions.ARB_texture_float) { + *params = img->TexFormat->IntensityBits ? img->TexFormat->DataType : GL_NONE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); + } + return; + case GL_TEXTURE_DEPTH_TYPE_ARB: + if (ctx->Extensions.ARB_texture_float) { + *params = img->TexFormat->DepthBits ? img->TexFormat->DataType : GL_NONE; + } + else { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetTexLevelParameter[if]v(pname)"); + } + return; + default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)"); @@ -1674,14 +1933,22 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, -void +void GLAPIENTRY _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) { - GET_CURRENT_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_unit *texUnit; struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexParameterfv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + obj = _mesa_select_tex_object(ctx, texUnit, target); if (!obj) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameterfv(target)"); @@ -1786,7 +2053,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) case GL_TEXTURE_LOD_BIAS: if (ctx->Extensions.EXT_texture_lod_bias) { *params = obj->LodBias; - break; + return; } break; default: @@ -1798,14 +2065,22 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ) } -void +void GLAPIENTRY _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) { - GET_CURRENT_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + struct gl_texture_unit *texUnit; struct gl_texture_object *obj; + GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureImageUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexParameteriv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + obj = _mesa_select_tex_object(ctx, texUnit, target); if (!obj) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexParameteriv(target)"); @@ -1815,12 +2090,6 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) switch (pname) { case GL_TEXTURE_MAG_FILTER: *params = (GLint) obj->MagFilter; - case GL_TEXTURE_LOD_BIAS: - if (ctx->Extensions.EXT_texture_lod_bias) { - *params = (GLint) obj->LodBias; - break; - } - break; return; case GL_TEXTURE_MIN_FILTER: *params = (GLint) obj->MinFilter; @@ -1920,6 +2189,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) return; } break; + case GL_TEXTURE_LOD_BIAS: + if (ctx->Extensions.EXT_texture_lod_bias) { + *params = (GLint) obj->LodBias; + return; + } + break; default: ; /* silence warnings */ } @@ -1935,12 +2210,11 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ) /**********************************************************************/ #if FEATURE_texgen -void +void GLAPIENTRY _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) { GET_CURRENT_CONTEXT(ctx); - GLuint tUnit = ctx->Texture.CurrentUnit; - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit]; + struct gl_texture_unit *texUnit; ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) @@ -1950,11 +2224,18 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) *params, _mesa_lookup_enum_by_nr((GLenum) (GLint) *params)); + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexGen(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + switch (coord) { case GL_S: if (pname==GL_TEXTURE_GEN_MODE) { GLenum mode = (GLenum) (GLint) *params; - GLuint bits; + GLbitfield bits; switch (mode) { case GL_OBJECT_LINEAR: bits = TEXGEN_OBJ_LINEAR; @@ -1985,16 +2266,12 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) if (TEST_EQ_4V(texUnit->ObjectPlaneS, params)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->ObjectPlaneS[0] = params[0]; - texUnit->ObjectPlaneS[1] = params[1]; - texUnit->ObjectPlaneS[2] = params[2]; - texUnit->ObjectPlaneS[3] = params[3]; + COPY_4FV(texUnit->ObjectPlaneS, params); } else if (pname==GL_EYE_PLANE) { GLfloat tmp[4]; - /* Transform plane equation by the inverse modelview matrix */ - if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) { + if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); } _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv ); @@ -2011,7 +2288,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) case GL_T: if (pname==GL_TEXTURE_GEN_MODE) { GLenum mode = (GLenum) (GLint) *params; - GLuint bitt; + GLbitfield bitt; switch (mode) { case GL_OBJECT_LINEAR: bitt = TEXGEN_OBJ_LINEAR; @@ -2042,15 +2319,12 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) if (TEST_EQ_4V(texUnit->ObjectPlaneT, params)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->ObjectPlaneT[0] = params[0]; - texUnit->ObjectPlaneT[1] = params[1]; - texUnit->ObjectPlaneT[2] = params[2]; - texUnit->ObjectPlaneT[3] = params[3]; + COPY_4FV(texUnit->ObjectPlaneT, params); } else if (pname==GL_EYE_PLANE) { GLfloat tmp[4]; /* Transform plane equation by the inverse modelview matrix */ - if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) { + if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); } _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv ); @@ -2067,7 +2341,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) case GL_R: if (pname==GL_TEXTURE_GEN_MODE) { GLenum mode = (GLenum) (GLint) *params; - GLuint bitr; + GLbitfield bitr; switch (mode) { case GL_OBJECT_LINEAR: bitr = TEXGEN_OBJ_LINEAR; @@ -2095,15 +2369,12 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) if (TEST_EQ_4V(texUnit->ObjectPlaneR, params)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->ObjectPlaneR[0] = params[0]; - texUnit->ObjectPlaneR[1] = params[1]; - texUnit->ObjectPlaneR[2] = params[2]; - texUnit->ObjectPlaneR[3] = params[3]; + COPY_4FV(texUnit->ObjectPlaneR, params); } else if (pname==GL_EYE_PLANE) { GLfloat tmp[4]; /* Transform plane equation by the inverse modelview matrix */ - if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) { + if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); } _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv ); @@ -2120,7 +2391,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) case GL_Q: if (pname==GL_TEXTURE_GEN_MODE) { GLenum mode = (GLenum) (GLint) *params; - GLuint bitq; + GLbitfield bitq; switch (mode) { case GL_OBJECT_LINEAR: bitq = TEXGEN_OBJ_LINEAR; @@ -2142,15 +2413,12 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) if (TEST_EQ_4V(texUnit->ObjectPlaneQ, params)) return; FLUSH_VERTICES(ctx, _NEW_TEXTURE); - texUnit->ObjectPlaneQ[0] = params[0]; - texUnit->ObjectPlaneQ[1] = params[1]; - texUnit->ObjectPlaneQ[2] = params[2]; - texUnit->ObjectPlaneQ[3] = params[3]; + COPY_4FV(texUnit->ObjectPlaneQ, params); } else if (pname==GL_EYE_PLANE) { GLfloat tmp[4]; /* Transform plane equation by the inverse modelview matrix */ - if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) { + if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); } _mesa_transform_vector( tmp, params, ctx->ModelviewMatrixStack.Top->inv ); @@ -2174,7 +2442,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) } -void +void GLAPIENTRY _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params ) { GLfloat p[4]; @@ -2191,7 +2459,7 @@ _mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params ) } -void +void GLAPIENTRY _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param ) { GLfloat p = (GLfloat) param; @@ -2199,7 +2467,7 @@ _mesa_TexGend(GLenum coord, GLenum pname, GLdouble param ) } -void +void GLAPIENTRY _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) { GLfloat p[4]; @@ -2216,14 +2484,14 @@ _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) } -void +void GLAPIENTRY _mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ) { _mesa_TexGenfv(coord, pname, ¶m); } -void +void GLAPIENTRY _mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) { _mesa_TexGeniv( coord, pname, ¶m ); @@ -2231,14 +2499,20 @@ _mesa_TexGeni( GLenum coord, GLenum pname, GLint param ) -void +void GLAPIENTRY _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) { + const struct gl_texture_unit *texUnit; GET_CURRENT_CONTEXT(ctx); - GLuint tUnit = ctx->Texture.CurrentUnit; - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit]; ASSERT_OUTSIDE_BEGIN_END(ctx); + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGendv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + switch (coord) { case GL_S: if (pname==GL_TEXTURE_GEN_MODE) { @@ -2308,14 +2582,20 @@ _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ) -void +void GLAPIENTRY _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) { + const struct gl_texture_unit *texUnit; GET_CURRENT_CONTEXT(ctx); - GLuint tUnit = ctx->Texture.CurrentUnit; - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit]; ASSERT_OUTSIDE_BEGIN_END(ctx); + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGenfv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + switch (coord) { case GL_S: if (pname==GL_TEXTURE_GEN_MODE) { @@ -2385,14 +2665,20 @@ _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ) -void +void GLAPIENTRY _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ) { + const struct gl_texture_unit *texUnit; GET_CURRENT_CONTEXT(ctx); - GLuint tUnit = ctx->Texture.CurrentUnit; - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[tUnit]; ASSERT_OUTSIDE_BEGIN_END(ctx); + if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexGeniv(current unit)"); + return; + } + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + switch (coord) { case GL_S: if (pname==GL_TEXTURE_GEN_MODE) { @@ -2485,21 +2771,22 @@ _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ) } #endif + /* GL_ARB_multitexture */ -void -_mesa_ActiveTextureARB( GLenum target ) +void GLAPIENTRY +_mesa_ActiveTextureARB(GLenum texture) { GET_CURRENT_CONTEXT(ctx); - const GLuint texUnit = target - GL_TEXTURE0; + const GLuint texUnit = texture - GL_TEXTURE0; ASSERT_OUTSIDE_BEGIN_END(ctx); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) _mesa_debug(ctx, "glActiveTexture %s\n", - _mesa_lookup_enum_by_nr(target)); + _mesa_lookup_enum_by_nr(texture)); - /* Cater for texture unit 0 is first, therefore use >= */ + /* XXX error-check against max(coordunits, imageunits) */ if (texUnit >= ctx->Const.MaxTextureUnits) { - _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(target)"); + _mesa_error(ctx, GL_INVALID_ENUM, "glActiveTexture(texture)"); return; } @@ -2521,15 +2808,15 @@ _mesa_ActiveTextureARB( GLenum target ) /* GL_ARB_multitexture */ -void -_mesa_ClientActiveTextureARB( GLenum target ) +void GLAPIENTRY +_mesa_ClientActiveTextureARB(GLenum texture) { GET_CURRENT_CONTEXT(ctx); - GLuint texUnit = target - GL_TEXTURE0; + GLuint texUnit = texture - GL_TEXTURE0; ASSERT_OUTSIDE_BEGIN_END(ctx); - if (texUnit > ctx->Const.MaxTextureUnits) { - _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(target)"); + if (texUnit >= ctx->Const.MaxTextureCoordUnits) { + _mesa_error(ctx, GL_INVALID_ENUM, "glClientActiveTexture(texture)"); return; } @@ -2539,138 +2826,6 @@ _mesa_ClientActiveTextureARB( GLenum target ) -/**********************************************************************/ -/* Pixel Texgen Extensions */ -/**********************************************************************/ - -void -_mesa_PixelTexGenSGIX(GLenum mode) -{ - GLenum newRgbSource, newAlphaSource; - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - switch (mode) { - case GL_NONE: - newRgbSource = GL_PIXEL_GROUP_COLOR_SGIS; - newAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS; - break; - case GL_ALPHA: - newRgbSource = GL_PIXEL_GROUP_COLOR_SGIS; - newAlphaSource = GL_CURRENT_RASTER_COLOR; - break; - case GL_RGB: - newRgbSource = GL_CURRENT_RASTER_COLOR; - newAlphaSource = GL_PIXEL_GROUP_COLOR_SGIS; - break; - case GL_RGBA: - newRgbSource = GL_CURRENT_RASTER_COLOR; - newAlphaSource = GL_CURRENT_RASTER_COLOR; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenSGIX(mode)"); - return; - } - - if (newRgbSource == ctx->Pixel.FragmentRgbSource && - newAlphaSource == ctx->Pixel.FragmentAlphaSource) - return; - - FLUSH_VERTICES(ctx, _NEW_PIXEL); - ctx->Pixel.FragmentRgbSource = newRgbSource; - ctx->Pixel.FragmentAlphaSource = newAlphaSource; -} - - -void -_mesa_PixelTexGenParameterfSGIS(GLenum target, GLfloat value) -{ - _mesa_PixelTexGenParameteriSGIS(target, (GLint) value); -} - - -void -_mesa_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value) -{ - _mesa_PixelTexGenParameteriSGIS(target, (GLint) *value); -} - - -void -_mesa_PixelTexGenParameteriSGIS(GLenum target, GLint value) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (value != GL_CURRENT_RASTER_COLOR && value != GL_PIXEL_GROUP_COLOR_SGIS) { - _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenParameterSGIS(value)"); - return; - } - - switch (target) { - case GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS: - if (ctx->Pixel.FragmentRgbSource == (GLenum) value) - return; - FLUSH_VERTICES(ctx, _NEW_PIXEL); - ctx->Pixel.FragmentRgbSource = (GLenum) value; - break; - case GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS: - if (ctx->Pixel.FragmentAlphaSource == (GLenum) value) - return; - FLUSH_VERTICES(ctx, _NEW_PIXEL); - ctx->Pixel.FragmentAlphaSource = (GLenum) value; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glPixelTexGenParameterSGIS(target)"); - return; - } -} - - -void -_mesa_PixelTexGenParameterivSGIS(GLenum target, const GLint *value) -{ - _mesa_PixelTexGenParameteriSGIS(target, *value); -} - - -void -_mesa_GetPixelTexGenParameterfvSGIS(GLenum target, GLfloat *value) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) { - *value = (GLfloat) ctx->Pixel.FragmentRgbSource; - } - else if (target == GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) { - *value = (GLfloat) ctx->Pixel.FragmentAlphaSource; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelTexGenParameterfvSGIS(target)"); - } -} - - -void -_mesa_GetPixelTexGenParameterivSGIS(GLenum target, GLint *value) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END(ctx); - - if (target == GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS) { - *value = (GLint) ctx->Pixel.FragmentRgbSource; - } - else if (target == GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS) { - *value = (GLint) ctx->Pixel.FragmentAlphaSource; - } - else { - _mesa_error(ctx, GL_INVALID_ENUM, "glGetPixelTexGenParameterivSGIS(target)"); - } -} - - - /**********************************************************************/ /***** State management *****/ /**********************************************************************/ @@ -2692,7 +2847,7 @@ update_texture_matrices( GLcontext *ctx ) ctx->Texture._TexMatEnabled = 0; for (i=0; i < ctx->Const.MaxTextureUnits; i++) { - if (ctx->TextureMatrixStack[i].Top->flags & MAT_DIRTY) { + if (_math_matrix_is_dirty(ctx->TextureMatrixStack[i].Top)) { _math_matrix_analyse( ctx->TextureMatrixStack[i].Top ); if (ctx->Texture.Unit[i]._ReallyEnabled && @@ -2706,6 +2861,25 @@ update_texture_matrices( GLcontext *ctx ) } +/** + * Helper function for determining which texture object (1D, 2D, cube, etc) + * should actually be used. + */ +static void +texture_override(GLcontext *ctx, + struct gl_texture_unit *texUnit, GLbitfield enableBits, + struct gl_texture_object *texObj, GLuint textureBit) +{ + if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) { + if (!texObj->Complete) { + _mesa_test_texobj_completeness(ctx, texObj); + } + if (texObj->Complete) { + texUnit->_ReallyEnabled = textureBit; + texUnit->_Current = texObj; + } + } +} /** @@ -2721,24 +2895,50 @@ update_texture_state( GLcontext *ctx ) { GLuint unit; +#if FEATURE_ARB_fragment_shader + struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram; + GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS]; +#endif + + ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are + * actual changes. + */ + ctx->Texture._EnabledUnits = 0; ctx->Texture._GenFlags = 0; ctx->Texture._TexMatEnabled = 0; ctx->Texture._TexGenEnabled = 0; - /* Update texture unit state. - * XXX this loop should probably be broken into separate loops for - * texture coord units and texture image units. +#if FEATURE_ARB_fragment_shader + /* + * Grab texture image usage state from shader program. It must be + * grabbed every time uniform sampler changes, so maybe there is a + * better place to perform these rather expensive computations. + */ + if (ctx->ShaderObjects._FragmentShaderPresent) { + (**prog).GetTextureImageUsage (prog, progteximageusage); + } +#endif /* FEATURE_ARB_fragment_shader */ + + /* + * Update texture unit state. */ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - GLuint enableBits; + GLbitfield enableBits; + texUnit->_Current = NULL; texUnit->_ReallyEnabled = 0; texUnit->_GenFlags = 0; /* Get the bitmask of texture enables */ - if (ctx->FragmentProgram.Enabled && ctx->FragmentProgram.Current) { +#if FEATURE_ARB_fragment_shader + if (ctx->ShaderObjects._FragmentShaderPresent) { + enableBits = progteximageusage[unit]; + } + else +#endif + if (ctx->FragmentProgram._Enabled) { enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit]; } else { @@ -2751,68 +2951,88 @@ update_texture_state( GLcontext *ctx ) * complete. That's the one we'll use for texturing. If we're using * a fragment program we're guaranteed that bitcount(enabledBits) <= 1. */ - if (texUnit->Enabled & TEXTURE_CUBE_BIT) { - struct gl_texture_object *texObj = texUnit->CurrentCubeMap; - if (!texObj->Complete) { - _mesa_test_texobj_completeness(ctx, texObj); - } - if (texObj->Complete) { - texUnit->_ReallyEnabled = TEXTURE_CUBE_BIT; - texUnit->_Current = texObj; - } - } + texture_override(ctx, texUnit, enableBits, + texUnit->CurrentCubeMap, TEXTURE_CUBE_BIT); + texture_override(ctx, texUnit, enableBits, + texUnit->Current3D, TEXTURE_3D_BIT); + texture_override(ctx, texUnit, enableBits, + texUnit->CurrentRect, TEXTURE_RECT_BIT); + texture_override(ctx, texUnit, enableBits, + texUnit->Current2D, TEXTURE_2D_BIT); + texture_override(ctx, texUnit, enableBits, + texUnit->Current1D, TEXTURE_1D_BIT); - if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_3D_BIT)) { - struct gl_texture_object *texObj = texUnit->Current3D; - if (!texObj->Complete) { - _mesa_test_texobj_completeness(ctx, texObj); - } - if (texObj->Complete) { - texUnit->_ReallyEnabled = TEXTURE_3D_BIT; - texUnit->_Current = texObj; - } + if (!texUnit->_ReallyEnabled) { + continue; } - if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_RECT_BIT)) { - struct gl_texture_object *texObj = texUnit->CurrentRect; - if (!texObj->Complete) { - _mesa_test_texobj_completeness(ctx, texObj); - } - if (texObj->Complete) { - texUnit->_ReallyEnabled = TEXTURE_RECT_BIT; - texUnit->_Current = texObj; - } - } + if (texUnit->_ReallyEnabled) + ctx->Texture._EnabledUnits |= (1 << unit); - if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_2D_BIT)) { - struct gl_texture_object *texObj = texUnit->Current2D; - if (!texObj->Complete) { - _mesa_test_texobj_completeness(ctx, texObj); - } - if (texObj->Complete) { - texUnit->_ReallyEnabled = TEXTURE_2D_BIT; - texUnit->_Current = texObj; - } + if (texUnit->EnvMode == GL_COMBINE) { + texUnit->_CurrentCombine = & texUnit->Combine; } - - if (!texUnit->_ReallyEnabled && (texUnit->Enabled & TEXTURE_1D_BIT)) { - struct gl_texture_object *texObj = texUnit->Current1D; - if (!texObj->Complete) { - _mesa_test_texobj_completeness(ctx, texObj); + else { + const struct gl_texture_object *texObj = texUnit->_Current; + GLenum format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat; + if (format == GL_COLOR_INDEX) { + format = GL_RGBA; /* a bit of a hack */ } - if (texObj->Complete) { - texUnit->_ReallyEnabled = TEXTURE_1D_BIT; - texUnit->_Current = texObj; + else if (format == GL_DEPTH_COMPONENT + || format == GL_DEPTH_STENCIL_EXT) { + format = texObj->DepthMode; } + calculate_derived_texenv(&texUnit->_EnvMode, texUnit->EnvMode, format); + texUnit->_CurrentCombine = & texUnit->_EnvMode; } - if (!texUnit->_ReallyEnabled) { - texUnit->_Current = NULL; - continue; + switch (texUnit->_CurrentCombine->ModeRGB) { + case GL_REPLACE: + texUnit->_CurrentCombine->_NumArgsRGB = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED: + case GL_SUBTRACT: + case GL_DOT3_RGB: + case GL_DOT3_RGBA: + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + texUnit->_CurrentCombine->_NumArgsRGB = 2; + break; + case GL_INTERPOLATE: + case GL_MODULATE_ADD_ATI: + case GL_MODULATE_SIGNED_ADD_ATI: + case GL_MODULATE_SUBTRACT_ATI: + texUnit->_CurrentCombine->_NumArgsRGB = 3; + break; + default: + texUnit->_CurrentCombine->_NumArgsRGB = 0; + _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state"); + return; } - if (texUnit->_ReallyEnabled) - ctx->Texture._EnabledUnits |= (1 << unit); + switch (texUnit->_CurrentCombine->ModeA) { + case GL_REPLACE: + texUnit->_CurrentCombine->_NumArgsA = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED: + case GL_SUBTRACT: + texUnit->_CurrentCombine->_NumArgsA = 2; + break; + case GL_INTERPOLATE: + case GL_MODULATE_ADD_ATI: + case GL_MODULATE_SIGNED_ADD_ATI: + case GL_MODULATE_SUBTRACT_ATI: + texUnit->_CurrentCombine->_NumArgsA = 3; + break; + default: + texUnit->_CurrentCombine->_NumArgsA = 0; + _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state"); + break; + } if (texUnit->TexGenEnabled) { if (texUnit->TexGenEnabled & S_BIT) { @@ -2840,9 +3060,12 @@ update_texture_state( GLcontext *ctx ) /* Fragment programs may need texture coordinates but not the * corresponding texture images. */ - if (ctx->FragmentProgram.Enabled && ctx->FragmentProgram.Current) { + if (ctx->ShaderObjects.CurrentProgram != NULL) { + ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1; + } + else if (ctx->FragmentProgram._Enabled) { ctx->Texture._EnabledCoordUnits |= - (ctx->FragmentProgram.Current->InputsRead >> FRAG_ATTRIB_TEX0); + (ctx->FragmentProgram.Current->Base.InputsRead >> FRAG_ATTRIB_TEX0); } } @@ -2852,10 +3075,11 @@ void _mesa_update_texture( GLcontext *ctx, GLuint new_state ) if (new_state & _NEW_TEXTURE_MATRIX) update_texture_matrices( ctx ); - if (new_state & _NEW_TEXTURE) + if (new_state & (_NEW_TEXTURE | _NEW_PROGRAM)) update_texture_state( ctx ); } + /**********************************************************************/ /***** Initialization *****/ /**********************************************************************/ @@ -2924,22 +3148,9 @@ init_texture_unit( GLcontext *ctx, GLuint unit ) texUnit->EnvMode = GL_MODULATE; ASSIGN_4V( texUnit->EnvColor, 0.0, 0.0, 0.0, 0.0 ); - texUnit->CombineModeRGB = GL_MODULATE; - texUnit->CombineModeA = GL_MODULATE; - texUnit->CombineSourceRGB[0] = GL_TEXTURE; - texUnit->CombineSourceRGB[1] = GL_PREVIOUS_EXT; - texUnit->CombineSourceRGB[2] = GL_CONSTANT_EXT; - texUnit->CombineSourceA[0] = GL_TEXTURE; - texUnit->CombineSourceA[1] = GL_PREVIOUS_EXT; - texUnit->CombineSourceA[2] = GL_CONSTANT_EXT; - texUnit->CombineOperandRGB[0] = GL_SRC_COLOR; - texUnit->CombineOperandRGB[1] = GL_SRC_COLOR; - texUnit->CombineOperandRGB[2] = GL_SRC_ALPHA; - texUnit->CombineOperandA[0] = GL_SRC_ALPHA; - texUnit->CombineOperandA[1] = GL_SRC_ALPHA; - texUnit->CombineOperandA[2] = GL_SRC_ALPHA; - texUnit->CombineScaleShiftRGB = 0; - texUnit->CombineScaleShiftA = 0; + texUnit->Combine = default_combine_state; + texUnit->_EnvMode = default_combine_state; + texUnit->_CurrentCombine = & texUnit->_EnvMode; texUnit->TexGenEnabled = 0; texUnit->GenModeS = GL_EYE_LINEAR; @@ -2969,9 +3180,13 @@ init_texture_unit( GLcontext *ctx, GLuint unit ) } -GLboolean _mesa_init_texture( GLcontext * ctx ) +/** + * Initialize texture state for the given context. + */ +GLboolean +_mesa_init_texture(GLcontext *ctx) { - int i; + GLuint i; assert(MAX_TEXTURE_LEVELS >= MAX_3D_TEXTURE_LEVELS); assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); @@ -2991,6 +3206,8 @@ GLboolean _mesa_init_texture( GLcontext * ctx ) ctx->Texture.SharedPalette = GL_FALSE; _mesa_init_colortable(&ctx->Texture.Palette); + _mesa_TexEnvProgramCacheInit( ctx ); + /* Allocate proxy textures */ if (!alloc_proxy_textures( ctx )) return GL_FALSE; @@ -2998,9 +3215,14 @@ GLboolean _mesa_init_texture( GLcontext * ctx ) return GL_TRUE; } -void _mesa_free_texture_data( GLcontext *ctx ) + +/** + * Free dynamically-allocted texture data attached to the given context. + */ +void +_mesa_free_texture_data(GLcontext *ctx) { - int i; + GLuint i; /* Free proxy texture objects */ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1D ); @@ -3011,4 +3233,6 @@ void _mesa_free_texture_data( GLcontext *ctx ) for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) _mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable ); + + _mesa_TexEnvProgramCacheDestroy( ctx ); }