summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/texstate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/texstate.c')
-rw-r--r--src/mesa/main/texstate.c123
1 files changed, 107 insertions, 16 deletions
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 1b45eae42c3..c9f8a0656e8 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
@@ -154,6 +154,10 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst )
src->Texture.Unit[i].CurrentCubeMap);
copy_texture_binding(src, &dst->Texture.Unit[i].CurrentRect,
src->Texture.Unit[i].CurrentRect);
+ copy_texture_binding(src, &dst->Texture.Unit[i].Current1DArray,
+ src->Texture.Unit[i].Current1DArray);
+ copy_texture_binding(src, &dst->Texture.Unit[i].Current2DArray,
+ src->Texture.Unit[i].Current2DArray);
_mesa_unlock_context_textures(dst);
}
@@ -1137,26 +1141,29 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
/* Texture Parameters */
/**********************************************************************/
+/**
+ * Check if a coordinate wrap mode is supported for the texture target.
+ * \return GL_TRUE if legal, GL_FALSE otherwise
+ */
static GLboolean
-_mesa_validate_texture_wrap_mode(GLcontext * ctx,
- GLenum target, GLenum eparam)
+validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
{
const struct gl_extensions * const e = & ctx->Extensions;
- if (eparam == GL_CLAMP || eparam == GL_CLAMP_TO_EDGE ||
- (eparam == GL_CLAMP_TO_BORDER && e->ARB_texture_border_clamp)) {
+ if (wrap == GL_CLAMP || wrap == GL_CLAMP_TO_EDGE ||
+ (wrap == 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 &&
+ (wrap == GL_REPEAT ||
+ (wrap == GL_MIRRORED_REPEAT &&
e->ARB_texture_mirrored_repeat) ||
- (eparam == GL_MIRROR_CLAMP_EXT &&
+ (wrap == GL_MIRROR_CLAMP_EXT &&
(e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
- (eparam == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
+ (wrap == GL_MIRROR_CLAMP_TO_EDGE_EXT &&
(e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp)) ||
- (eparam == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
+ (wrap == GL_MIRROR_CLAMP_TO_BORDER_EXT &&
(e->EXT_texture_mirror_clamp)))) {
/* non-rectangle texture */
return GL_TRUE;
@@ -1221,6 +1228,20 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
}
texObj = texUnit->CurrentRect;
break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ if (!ctx->Extensions.MESA_texture_array) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
+ return;
+ }
+ texObj = texUnit->Current1DArray;
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ if (!ctx->Extensions.MESA_texture_array) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
+ return;
+ }
+ texObj = texUnit->Current2DArray;
+ break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(target)" );
return;
@@ -1265,7 +1286,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
case GL_TEXTURE_WRAP_S:
if (texObj->WrapS == eparam)
return;
- if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texObj->WrapS = eparam;
}
@@ -1276,7 +1297,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
case GL_TEXTURE_WRAP_T:
if (texObj->WrapT == eparam)
return;
- if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texObj->WrapT = eparam;
}
@@ -1287,7 +1308,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
case GL_TEXTURE_WRAP_R:
if (texObj->WrapR == eparam)
return;
- if (_mesa_validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
+ if (validate_texture_wrap_mode(ctx, texObj->Target, eparam)) {
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texObj->WrapR = eparam;
}
@@ -1497,7 +1518,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
return;
}
- texObj->Complete = GL_FALSE;
+ texObj->_Complete = GL_FALSE;
if (ctx->Driver.TexParameter) {
(*ctx->Driver.TexParameter)( ctx, target, texObj, pname, params );
@@ -1574,6 +1595,12 @@ tex_image_dimensions(GLcontext *ctx, GLenum target)
case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array ? 2 : 0;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array ? 3 : 0;
default:
_mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
return 0;
@@ -2769,6 +2796,47 @@ update_texture_matrices( GLcontext *ctx )
/**
+ * Update texture object's _Function field. We need to do this
+ * whenever any of the texture object's shadow-related fields change
+ * or when we start/stop using a fragment program.
+ *
+ * This function could be expanded someday to update additional per-object
+ * fields that depend on assorted state changes.
+ */
+static void
+update_texture_compare_function(GLcontext *ctx,
+ struct gl_texture_object *tObj)
+{
+ /* XXX temporarily disable this test since it breaks the GLSL
+ * shadow2D(), etc. functions.
+ */
+ if (0 /*ctx->FragmentProgram._Current*/) {
+ /* Texel/coordinate comparison is ignored for programs.
+ * See GL_ARB_fragment_program/shader spec for details.
+ */
+ tObj->_Function = GL_NONE;
+ }
+ else if (tObj->CompareFlag) {
+ /* GL_SGIX_shadow */
+ if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
+ tObj->_Function = GL_LEQUAL;
+ }
+ else {
+ ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
+ tObj->_Function = GL_GEQUAL;
+ }
+ }
+ else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
+ /* GL_ARB_shadow */
+ tObj->_Function = tObj->CompareFunc;
+ }
+ else {
+ tObj->_Function = GL_NONE; /* pass depth through as grayscale */
+ }
+}
+
+
+/**
* Helper function for determining which texture object (1D, 2D, cube, etc)
* should actually be used.
*/
@@ -2778,12 +2846,13 @@ texture_override(GLcontext *ctx,
struct gl_texture_object *texObj, GLuint textureBit)
{
if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) {
- if (!texObj->Complete) {
+ if (!texObj->_Complete) {
_mesa_test_texobj_completeness(ctx, texObj);
}
- if (texObj->Complete) {
+ if (texObj->_Complete) {
texUnit->_ReallyEnabled = textureBit;
texUnit->_Current = texObj;
+ update_texture_compare_function(ctx, texObj);
}
}
}
@@ -2865,6 +2934,10 @@ update_texture_state( GLcontext *ctx )
* a fragment program we're guaranteed that bitcount(enabledBits) <= 1.
*/
texture_override(ctx, texUnit, enableBits,
+ texUnit->Current2DArray, TEXTURE_2D_ARRAY_BIT);
+ texture_override(ctx, texUnit, enableBits,
+ texUnit->Current1DArray, TEXTURE_1D_ARRAY_BIT);
+ texture_override(ctx, texUnit, enableBits,
texUnit->CurrentCubeMap, TEXTURE_CUBE_BIT);
texture_override(ctx, texUnit, enableBits,
texUnit->Current3D, TEXTURE_3D_BIT);
@@ -3032,6 +3105,14 @@ alloc_proxy_textures( GLcontext *ctx )
if (!ctx->Texture.ProxyRect)
goto cleanup;
+ ctx->Texture.Proxy1DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D_ARRAY_EXT);
+ if (!ctx->Texture.Proxy1DArray)
+ goto cleanup;
+
+ ctx->Texture.Proxy2DArray = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_2D_ARRAY_EXT);
+ if (!ctx->Texture.Proxy2DArray)
+ goto cleanup;
+
return GL_TRUE;
cleanup:
@@ -3045,6 +3126,10 @@ alloc_proxy_textures( GLcontext *ctx )
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap);
if (ctx->Texture.ProxyRect)
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect);
+ if (ctx->Texture.Proxy1DArray)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray);
+ if (ctx->Texture.Proxy2DArray)
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray);
return GL_FALSE;
}
@@ -3092,6 +3177,8 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
texUnit->Current3D = ctx->Shared->Default3D;
texUnit->CurrentCubeMap = ctx->Shared->DefaultCubeMap;
texUnit->CurrentRect = ctx->Shared->DefaultRect;
+ texUnit->Current1DArray = ctx->Shared->Default1DArray;
+ texUnit->Current2DArray = ctx->Shared->Default2DArray;
}
@@ -3112,6 +3199,8 @@ _mesa_init_texture(GLcontext *ctx)
ctx->Shared->Default3D->RefCount += MAX_TEXTURE_UNITS;
ctx->Shared->DefaultCubeMap->RefCount += MAX_TEXTURE_UNITS;
ctx->Shared->DefaultRect->RefCount += MAX_TEXTURE_UNITS;
+ ctx->Shared->Default1DArray->RefCount += MAX_TEXTURE_UNITS;
+ ctx->Shared->Default2DArray->RefCount += MAX_TEXTURE_UNITS;
/* Texture group */
ctx->Texture.CurrentUnit = 0; /* multitexture */
@@ -3145,6 +3234,8 @@ _mesa_free_texture_data(GLcontext *ctx)
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy3D );
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyCubeMap );
(ctx->Driver.DeleteTexture)(ctx, ctx->Texture.ProxyRect );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy1DArray );
+ (ctx->Driver.DeleteTexture)(ctx, ctx->Texture.Proxy2DArray );
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
_mesa_free_colortable_data( &ctx->Texture.Unit[i].ColorTable );