/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.1
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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 "glheader.h"
+#include "mfeatures.h"
+#if FEATURE_colortable
#include "colortab.h"
+#endif
#include "context.h"
#include "enums.h"
#include "fbobject.h"
#include "texstate.h"
#include "texobj.h"
#include "mtypes.h"
+#include "shader/prog_instruction.h"
+
/**********************************************************************/
obj->BaseLevel = 0;
obj->MaxLevel = 1000;
obj->MaxAnisotropy = 1.0;
- obj->CompareFlag = GL_FALSE; /* SGIX_shadow */
- obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX; /* SGIX_shadow */
obj->CompareMode = GL_NONE; /* ARB_shadow */
obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */
+ obj->CompareFailValue = 0.0F; /* ARB_shadow_ambient */
obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */
- obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */
+ obj->Swizzle[0] = GL_RED;
+ obj->Swizzle[1] = GL_GREEN;
+ obj->Swizzle[2] = GL_BLUE;
+ obj->Swizzle[3] = GL_ALPHA;
+ obj->_Swizzle = SWIZZLE_NOOP;
+}
+
+
+/**
+ * Some texture initialization can't be finished until we know which
+ * target it's getting bound to (GL_TEXTURE_1D/2D/etc).
+ */
+static void
+finish_texture_init(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *obj)
+{
+ assert(obj->Target == 0);
+
+ if (target == GL_TEXTURE_RECTANGLE_NV) {
+ /* have to init wrap and filter state here - kind of klunky */
+ obj->WrapS = GL_CLAMP_TO_EDGE;
+ obj->WrapT = GL_CLAMP_TO_EDGE;
+ obj->WrapR = GL_CLAMP_TO_EDGE;
+ obj->MinFilter = GL_LINEAR;
+ if (ctx->Driver.TexParameter) {
+ static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
+ static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
+ ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_MIN_FILTER, fparam_filter);
+ }
+ }
}
* Called via ctx->Driver.DeleteTexture() if not overriden by a driver.
*
* \param shared the shared GL state to which the object belongs.
- * \param texOjb the texture object to delete.
+ * \param texObj the texture object to delete.
*/
void
_mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
{
GLuint i, face;
- /*
- printf("TEX DELETE %p (%u)\n", (void*) texObj, texObj->Name);
- */
-
(void) ctx;
/* Set Target to an invalid value. With some assertions elsewhere
*/
texObj->Target = 0x99;
+#if FEATURE_colortable
_mesa_free_colortable_data(&texObj->Palette);
+#endif
/* free the texture images */
for (face = 0; face < 6; face++) {
_mesa_copy_texture_object( struct gl_texture_object *dest,
const struct gl_texture_object *src )
{
+ dest->Target = src->Target;
dest->Name = src->Name;
dest->Priority = src->Priority;
dest->BorderColor[0] = src->BorderColor[0];
dest->BaseLevel = src->BaseLevel;
dest->MaxLevel = src->MaxLevel;
dest->MaxAnisotropy = src->MaxAnisotropy;
- dest->CompareFlag = src->CompareFlag;
- dest->CompareOperator = src->CompareOperator;
- dest->ShadowAmbient = src->ShadowAmbient;
dest->CompareMode = src->CompareMode;
dest->CompareFunc = src->CompareFunc;
+ dest->CompareFailValue = src->CompareFailValue;
dest->DepthMode = src->DepthMode;
dest->_MaxLevel = src->_MaxLevel;
dest->_MaxLambda = src->_MaxLambda;
dest->GenerateMipmap = src->GenerateMipmap;
dest->Palette = src->Palette;
dest->_Complete = src->_Complete;
+ COPY_4V(dest->Swizzle, src->Swizzle);
+ dest->_Swizzle = src->_Swizzle;
}
_glthread_LOCK_MUTEX(oldTex->Mutex);
ASSERT(oldTex->RefCount > 0);
oldTex->RefCount--;
- /*
- printf("TEX DECR %p (%u) to %d\n",
- (void*) oldTex, oldTex->Name, oldTex->RefCount);
- */
+
deleteFlag = (oldTex->RefCount == 0);
_glthread_UNLOCK_MUTEX(oldTex->Mutex);
if (deleteFlag) {
GET_CURRENT_CONTEXT(ctx);
- ctx->Driver.DeleteTexture(ctx, oldTex);
+ if (ctx)
+ ctx->Driver.DeleteTexture(ctx, oldTex);
+ else
+ _mesa_problem(NULL, "Unable to delete texture, no context");
}
*ptr = NULL;
}
else {
tex->RefCount++;
- /*
- printf("TEX INCR %p (%u) to %d\n",
- (void*) tex, tex->Name, tex->RefCount);
- */
*ptr = tex;
}
_glthread_UNLOCK_MUTEX(tex->Mutex);
t->_Complete = GL_TRUE; /* be optimistic */
+ /* Detect cases where the application set the base level to an invalid
+ * value.
+ */
+ if ((baseLevel < 0) || (baseLevel > MAX_TEXTURE_LEVELS)) {
+ char s[100];
+ _mesa_sprintf(s, "base level = %d is invalid", baseLevel);
+ incomplete(t, s);
+ t->_Complete = GL_FALSE;
+ return;
+ }
+
/* Always need the base level image */
if (!t->Image[0][baseLevel]) {
char s[100];
- _mesa_sprintf(s, "obj %p (%d) Image[baseLevel=%d] == NULL",
- (void *) t, t->Name, baseLevel);
+ _mesa_sprintf(s, "Image[baseLevel=%d] == NULL", baseLevel);
incomplete(t, s);
t->_Complete = GL_FALSE;
return;
static void
unbind_texobj_from_texunits(GLcontext *ctx, struct gl_texture_object *texObj)
{
- GLuint u;
+ GLuint u, tex;
for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++) {
struct gl_texture_unit *unit = &ctx->Texture.Unit[u];
- if (texObj == unit->Current1D) {
- _mesa_reference_texobj(&unit->Current1D, ctx->Shared->Default1D);
- }
- else if (texObj == unit->Current2D) {
- _mesa_reference_texobj(&unit->Current2D, ctx->Shared->Default2D);
- }
- else if (texObj == unit->Current3D) {
- _mesa_reference_texobj(&unit->Current3D, ctx->Shared->Default3D);
- }
- else if (texObj == unit->CurrentCubeMap) {
- _mesa_reference_texobj(&unit->CurrentCubeMap, ctx->Shared->DefaultCubeMap);
- }
- else if (texObj == unit->CurrentRect) {
- _mesa_reference_texobj(&unit->CurrentRect, ctx->Shared->DefaultRect);
- }
- else if (texObj == unit->Current1DArray) {
- _mesa_reference_texobj(&unit->Current1DArray, ctx->Shared->Default1DArray);
- }
- else if (texObj == unit->Current2DArray) {
- _mesa_reference_texobj(&unit->Current2DArray, ctx->Shared->Default2DArray);
+ for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) {
+ if (texObj == unit->CurrentTex[tex]) {
+ _mesa_reference_texobj(&unit->CurrentTex[tex],
+ ctx->Shared->DefaultTex[TEXTURE_1D_INDEX]);
+ ASSERT(unit->CurrentTex[tex]);
+ break;
+ }
}
}
}
_mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name);
_glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
- /* Unrefernce the texobj. If refcount hits zero, the texture
+ /* Unreference the texobj. If refcount hits zero, the texture
* will be deleted.
*/
_mesa_reference_texobj(&delObj, NULL);
}
+/**
+ * Convert a GL texture target enum such as GL_TEXTURE_2D or GL_TEXTURE_3D
+ * into the corresponding Mesa texture target index.
+ * Return -1 if target is invalid.
+ */
+static GLint
+target_enum_to_index(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ return TEXTURE_1D_INDEX;
+ case GL_TEXTURE_2D:
+ return TEXTURE_2D_INDEX;
+ case GL_TEXTURE_3D:
+ return TEXTURE_3D_INDEX;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ return TEXTURE_CUBE_INDEX;
+ case GL_TEXTURE_RECTANGLE_NV:
+ return TEXTURE_RECT_INDEX;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ return TEXTURE_1D_ARRAY_INDEX;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ return TEXTURE_2D_ARRAY_INDEX;
+ default:
+ return -1;
+ }
+}
+
+
/**
* Bind a named texture to a texturing target.
*
GET_CURRENT_CONTEXT(ctx);
const GLuint unit = ctx->Texture.CurrentUnit;
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- struct gl_texture_object *newTexObj = NULL;
+ struct gl_texture_object *newTexObj = NULL, *defaultTexObj = NULL;
+ GLint targetIndex;
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
_mesa_debug(ctx, "glBindTexture %s %d\n",
_mesa_lookup_enum_by_nr(target), (GLint) texName);
+ targetIndex = target_enum_to_index(target);
+ if (targetIndex < 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindTexture(target)");
+ return;
+ }
+ assert(targetIndex < NUM_TEXTURE_TARGETS);
+ defaultTexObj = ctx->Shared->DefaultTex[targetIndex];
+
/*
* Get pointer to new texture object (newTexObj)
*/
if (texName == 0) {
- /* newTexObj = a default texture object */
- switch (target) {
- case GL_TEXTURE_1D:
- newTexObj = ctx->Shared->Default1D;
- break;
- case GL_TEXTURE_2D:
- newTexObj = ctx->Shared->Default2D;
- break;
- case GL_TEXTURE_3D:
- newTexObj = ctx->Shared->Default3D;
- break;
- case GL_TEXTURE_CUBE_MAP_ARB:
- newTexObj = ctx->Shared->DefaultCubeMap;
- break;
- case GL_TEXTURE_RECTANGLE_NV:
- newTexObj = ctx->Shared->DefaultRect;
- break;
- case GL_TEXTURE_1D_ARRAY_EXT:
- newTexObj = ctx->Shared->Default1DArray;
- break;
- case GL_TEXTURE_2D_ARRAY_EXT:
- newTexObj = ctx->Shared->Default2DArray;
- break;
- default:
- ; /* Bad targets are caught above */
- }
+ newTexObj = defaultTexObj;
}
else {
/* non-default texture object */
if (newTexObj) {
/* error checking */
if (newTexObj->Target != 0 && newTexObj->Target != target) {
- /* the named texture object's dimensions don't match the target */
+ /* the named texture object's target doesn't match the given target */
_mesa_error( ctx, GL_INVALID_OPERATION,
- "glBindTexture(wrong dimensionality)" );
+ "glBindTexture(target mismatch)" );
return;
}
- if (newTexObj->Target == 0 && target == GL_TEXTURE_RECTANGLE_NV) {
- /* have to init wrap and filter state here - kind of klunky */
- newTexObj->WrapS = GL_CLAMP_TO_EDGE;
- newTexObj->WrapT = GL_CLAMP_TO_EDGE;
- newTexObj->WrapR = GL_CLAMP_TO_EDGE;
- newTexObj->MinFilter = GL_LINEAR;
- if (ctx->Driver.TexParameter) {
- static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
- static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
- (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_S, fparam_wrap );
- (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_T, fparam_wrap );
- (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_WRAP_R, fparam_wrap );
- (*ctx->Driver.TexParameter)( ctx, target, newTexObj, GL_TEXTURE_MIN_FILTER, fparam_filter );
- }
+ if (newTexObj->Target == 0) {
+ finish_texture_init(ctx, target, newTexObj);
}
}
else {
* texture object will be decremented. It'll be deleted if the
* count hits zero.
*/
- switch (target) {
- case GL_TEXTURE_1D:
- _mesa_reference_texobj(&texUnit->Current1D, newTexObj);
- break;
- case GL_TEXTURE_2D:
- _mesa_reference_texobj(&texUnit->Current2D, newTexObj);
- break;
- case GL_TEXTURE_3D:
- _mesa_reference_texobj(&texUnit->Current3D, newTexObj);
- break;
- case GL_TEXTURE_CUBE_MAP_ARB:
- _mesa_reference_texobj(&texUnit->CurrentCubeMap, newTexObj);
- break;
- case GL_TEXTURE_RECTANGLE_NV:
- _mesa_reference_texobj(&texUnit->CurrentRect, newTexObj);
- break;
- case GL_TEXTURE_1D_ARRAY_EXT:
- texUnit->Current1DArray = newTexObj;
- break;
- case GL_TEXTURE_2D_ARRAY_EXT:
- texUnit->Current2DArray = newTexObj;
- break;
- default:
- _mesa_problem(ctx, "bad target in BindTexture");
- return;
- }
+ _mesa_reference_texobj(&texUnit->CurrentTex[targetIndex], newTexObj);
+ ASSERT(texUnit->CurrentTex[targetIndex]);
/* Pass BindTexture call to device driver */
if (ctx->Driver.BindTexture)