/*
* 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"),
#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
};
+/**
+ * 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 )
{
dst->Texture.Unit[i].Combine.ScaleShiftRGB = src->Texture.Unit[i].Combine.ScaleShiftRGB;
dst->Texture.Unit[i].Combine.ScaleShiftA = src->Texture.Unit[i].Combine.ScaleShiftA;
- /* 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);
+ /* 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);
}
}
* \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 tex_base_format Base format of the texture associated with the
+ * \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 tex_base_format )
+calculate_derived_texenv( struct gl_tex_env_combine_state *state,
+ GLenum mode, GLenum texBaseFormat )
{
GLenum mode_rgb;
GLenum mode_a;
*state = default_combine_state;
- switch( tex_base_format ) {
+ switch (texBaseFormat) {
case GL_ALPHA:
state->SourceRGB[0] = GL_PREVIOUS;
break;
break;
default:
- state->SourceRGB[0] = GL_PREVIOUS;
- state->SourceA[0] = GL_PREVIOUS;
- state->ModeRGB = GL_REPLACE;
- state->ModeA = GL_REPLACE;
- ASSERT(0);
+ _mesa_problem(NULL, "Invalid texBaseFormat in calculate_derived_texenv");
return;
}
- switch( mode ) {
+ switch (mode) {
case GL_REPLACE:
case GL_MODULATE:
- mode_rgb = (tex_base_format == GL_ALPHA) ? GL_REPLACE : mode;
+ mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : mode;
mode_a = mode;
break;
* incoming fragment color matches the definition in NV_texture_shader.
* The 1.5 spec simply marks these as "undefined".
*/
- switch( tex_base_format ) {
+ switch (texBaseFormat) {
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
mode_rgb = GL_INTERPOLATE;
mode_a = GL_MODULATE;
- switch( tex_base_format ) {
+ 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:
break;
case GL_ADD:
- mode_rgb = (tex_base_format == GL_ALPHA) ? GL_REPLACE : GL_ADD;
- mode_a = (tex_base_format == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
+ mode_rgb = (texBaseFormat == GL_ALPHA) ? GL_REPLACE : GL_ADD;
+ mode_a = (texBaseFormat == GL_INTENSITY) ? GL_ADD : GL_MODULATE;
break;
default:
- mode_rgb = GL_REPLACE;
- mode_a = GL_REPLACE;
- ASSERT(0);
- break;
+ _mesa_problem(NULL,
+ "Invalid texture env mode in calculate_derived_texenv");
+ return;
}
state->ModeRGB = (state->SourceRGB[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));
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 ||
(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;
-
- /* FIXME: Is this needed here or is having it in
- * FIXME: update_texture_state enough?
- */
- if ( mode == GL_COMBINE ) {
- texUnit->_CurrentCombine = & texUnit->Combine;
- }
- else if ( texUnit->_Current != NULL ) {
- calculate_derived_texenv( & texUnit->_EnvMode, mode,
- texUnit->_Current->Image[0][0]->Format );
- texUnit->_CurrentCombine = & texUnit->_EnvMode;
- }
}
else {
TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
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:
TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
return;
}
- if (texUnit->Combine.ModeRGB == mode)
- return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->Combine.ModeRGB = mode;
}
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:
TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
return;
}
-
- if (texUnit->Combine.ModeA == mode)
- return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->Combine.ModeA = mode;
}
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 ||
(ctx->Extensions.ATI_texture_env_combine3 &&
(source == GL_ZERO || source == GL_ONE))) {
/* legal */
- if (texUnit->Combine.SourceRGB[s] == source)
- return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->Combine.SourceRGB[s] = source;
}
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 ||
(ctx->Extensions.ATI_texture_env_combine3 &&
(source == GL_ZERO || source == GL_ONE))) {
/* legal */
- if (texUnit->Combine.SourceA[s] == source)
- return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->Combine.SourceA[s] = source;
}
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->Combine.OperandRGB[s] == operand)
- return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->Combine.OperandRGB[s] = operand;
break;
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->Combine.OperandA[pname-GL_OPERAND0_ALPHA] ==
- operand)
- return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->Combine.OperandA[pname-GL_OPERAND0_ALPHA] = operand;
break;
}
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->Combine.OperandRGB[2] == operand)
- return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->Combine.OperandRGB[2] = operand;
break;
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->Combine.OperandA[2] == operand)
- return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->Combine.OperandA[2] = operand;
break;
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;
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:
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:
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))
*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:
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,
_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) {
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 <target> was just checked above */
+ _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
return;
}
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:
*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;
*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;
*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,
}
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)");
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)");
case GL_TEXTURE_LOD_BIAS:
if (ctx->Extensions.EXT_texture_lod_bias) {
*params = obj->LodBias;
- break;
+ return;
}
break;
default:
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)");
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;
return;
}
break;
+ case GL_TEXTURE_LOD_BIAS:
+ if (ctx->Extensions.EXT_texture_lod_bias) {
+ *params = (GLint) obj->LodBias;
+ return;
+ }
+ break;
default:
; /* silence warnings */
}
_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))
*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;
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 );
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;
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 );
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;
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 );
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;
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 );
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) {
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) {
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) {
}
#endif
+
/* GL_ARB_multitexture */
void GLAPIENTRY
-_mesa_ActiveTextureARB( GLenum target )
+_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;
}
/* GL_ARB_multitexture */
void GLAPIENTRY
-_mesa_ClientActiveTextureARB( GLenum target )
+_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;
}
-/**********************************************************************/
-/* Pixel Texgen Extensions */
-/**********************************************************************/
-
-void GLAPIENTRY
-_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 GLAPIENTRY
-_mesa_PixelTexGenParameterfSGIS(GLenum target, GLfloat value)
-{
- _mesa_PixelTexGenParameteriSGIS(target, (GLint) value);
-}
-
-
-void GLAPIENTRY
-_mesa_PixelTexGenParameterfvSGIS(GLenum target, const GLfloat *value)
-{
- _mesa_PixelTexGenParameteriSGIS(target, (GLint) *value);
-}
-
-
-void GLAPIENTRY
-_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 GLAPIENTRY
-_mesa_PixelTexGenParameterivSGIS(GLenum target, const GLint *value)
-{
- _mesa_PixelTexGenParameteriSGIS(target, *value);
-}
-
-
-void GLAPIENTRY
-_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 GLAPIENTRY
-_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 *****/
/**********************************************************************/
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 &&
}
+/**
+ * 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;
+ }
+ }
+}
/**
{
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._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 {
* 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 (enableBits & 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;
- }
- }
-
- if (!texUnit->_ReallyEnabled && (enableBits & 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 && (enableBits & 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 && (enableBits & 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->_ReallyEnabled && (enableBits & TEXTURE_1D_BIT)) {
- struct gl_texture_object *texObj = texUnit->Current1D;
- if (!texObj->Complete) {
- _mesa_test_texobj_completeness(ctx, texObj);
- }
- if (texObj->Complete) {
- texUnit->_ReallyEnabled = TEXTURE_1D_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) {
continue;
if (texUnit->_ReallyEnabled)
ctx->Texture._EnabledUnits |= (1 << unit);
- if ( texUnit->EnvMode == GL_COMBINE ) {
+ if (texUnit->EnvMode == GL_COMBINE) {
texUnit->_CurrentCombine = & texUnit->Combine;
}
else {
- calculate_derived_texenv( & texUnit->_EnvMode,
- texUnit->EnvMode,
- texUnit->_Current->Image[0][0]->Format );
+ 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 */
+ }
+ 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;
}
break;
default:
texUnit->_CurrentCombine->_NumArgsRGB = 0;
- ASSERT(0);
- break;
+ _mesa_problem(ctx, "invalid RGB combine mode in update_texture_state");
+ return;
}
switch (texUnit->_CurrentCombine->ModeA) {
break;
default:
texUnit->_CurrentCombine->_NumArgsA = 0;
- ASSERT(0);
+ _mesa_problem(ctx, "invalid Alpha combine mode in update_texture_state");
break;
}
/* 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);
}
}
update_texture_state( ctx );
}
+
/**********************************************************************/
/***** Initialization *****/
/**********************************************************************/
}
-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);
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;
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 );
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
_mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );
+
+ _mesa_TexEnvProgramCacheDestroy( ctx );
}