Implemented GL_NV_texture_rectangle extension.

Replace struct gl_texure_object's Dimension w/ Target field.
Added _EnabledUnits to struct gl_texture_attrib - the _ReallyEnabled
  field is obsolete, but still present for now.  This effectively
  removes the 8-texture units limit, 32 units now possible, but unlikely!
New TEXTURE_1D/2D/3D/CUBE/RECT_BIT tokens for unit->_ReallyEnabled field.
Updated device drivers to use ctx->Texture._EnabledUnits.
This commit is contained in:
Brian Paul
2002-06-15 03:03:06 +00:00
parent 8bdd0dc8d0
commit 8afe7de8de
37 changed files with 921 additions and 371 deletions

View File

@@ -1,4 +1,4 @@
/* $Id: texobj.c,v 1.54 2002/06/15 02:38:16 brianp Exp $ */
/* $Id: texobj.c,v 1.55 2002/06/15 03:03:09 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -49,17 +49,23 @@
* table.
* Input: shared - the shared GL state structure to contain the texture object
* name - integer name for the texture object
* dimensions - either 1, 2, 3 or 6 (cube map)
* target - either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D,
* GL_TEXTURE_CUBE_MAP_ARB or GL_TEXTURE_RECTANGLE_NV
* zero is ok for the sake of GenTextures()
* Return: pointer to new texture object
*/
struct gl_texture_object *
_mesa_alloc_texture_object( struct gl_shared_state *shared,
GLuint name, GLuint dimensions )
GLuint name, GLenum target )
{
struct gl_texture_object *obj;
ASSERT(dimensions <= 3 || dimensions == 6);
ASSERT(target == 0 ||
target == GL_TEXTURE_1D ||
target == GL_TEXTURE_2D ||
target == GL_TEXTURE_3D ||
target == GL_TEXTURE_CUBE_MAP_ARB ||
target == GL_TEXTURE_RECTANGLE_NV);
obj = CALLOC_STRUCT(gl_texture_object);
@@ -68,12 +74,20 @@ _mesa_alloc_texture_object( struct gl_shared_state *shared,
_glthread_INIT_MUTEX(obj->Mutex);
obj->RefCount = 1;
obj->Name = name;
obj->Dimensions = dimensions;
obj->Target = target;
obj->Priority = 1.0F;
obj->WrapS = GL_REPEAT;
obj->WrapT = GL_REPEAT;
obj->WrapR = GL_REPEAT;
obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
if (target == GL_TEXTURE_RECTANGLE_NV) {
obj->WrapS = GL_CLAMP_TO_EDGE;
obj->WrapT = GL_CLAMP_TO_EDGE;
obj->WrapR = GL_CLAMP_TO_EDGE;
obj->MinFilter = GL_LINEAR;
}
else {
obj->WrapS = GL_REPEAT;
obj->WrapT = GL_REPEAT;
obj->WrapR = GL_REPEAT;
obj->MinFilter = GL_NEAREST_MIPMAP_LINEAR;
}
obj->MagFilter = GL_LINEAR;
obj->MinLod = -1000.0;
obj->MaxLod = 1000.0;
@@ -196,24 +210,32 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
/* Compute _MaxLevel */
if (t->Dimensions == 1) {
if (t->Target == GL_TEXTURE_1D) {
maxLog2 = t->Image[baseLevel]->WidthLog2;
maxLevels = ctx->Const.MaxTextureLevels;
}
else if (t->Dimensions == 2 || t->Dimensions == 6) {
else if (t->Target == GL_TEXTURE_2D) {
maxLog2 = MAX2(t->Image[baseLevel]->WidthLog2,
t->Image[baseLevel]->HeightLog2);
maxLevels = (t->Dimensions == 2) ?
ctx->Const.MaxTextureLevels : ctx->Const.MaxCubeTextureLevels;
maxLevels = ctx->Const.MaxTextureLevels;
}
else if (t->Dimensions == 3) {
else if (t->Target == GL_TEXTURE_3D) {
GLint max = MAX2(t->Image[baseLevel]->WidthLog2,
t->Image[baseLevel]->HeightLog2);
maxLog2 = MAX2(max, (GLint)(t->Image[baseLevel]->DepthLog2));
maxLevels = ctx->Const.Max3DTextureLevels;
}
else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
maxLog2 = MAX2(t->Image[baseLevel]->WidthLog2,
t->Image[baseLevel]->HeightLog2);
maxLevels = ctx->Const.MaxCubeTextureLevels;
}
else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
maxLog2 = 0; /* not applicable */
maxLevels = 1; /* no mipmapping */
}
else {
_mesa_problem(ctx, "Bad t->Dimension in _mesa_test_texobj_completeness");
_mesa_problem(ctx, "Bad t->Target in _mesa_test_texobj_completeness");
return;
}
@@ -226,7 +248,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
/* Compute _MaxLambda = q - b (see the 1.2 spec) used during mipmapping */
t->_MaxLambda = (GLfloat) (t->_MaxLevel - t->BaseLevel);
if (t->Dimensions == 6) {
if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
/* make sure that all six cube map level 0 images are the same size */
const GLuint w = t->Image[baseLevel]->Width2;
const GLuint h = t->Image[baseLevel]->Height2;
@@ -282,7 +304,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
/* Test things which depend on number of texture image dimensions */
if (t->Dimensions == 1) {
if (t->Target == GL_TEXTURE_1D) {
/* Test 1-D mipmaps */
GLuint width = t->Image[baseLevel]->Width2;
for (i = baseLevel + 1; i < maxLevels; i++) {
@@ -306,7 +328,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
}
}
else if (t->Dimensions == 2) {
else if (t->Target == GL_TEXTURE_2D) {
/* Test 2-D mipmaps */
GLuint width = t->Image[baseLevel]->Width2;
GLuint height = t->Image[baseLevel]->Height2;
@@ -339,7 +361,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
}
}
else if (t->Dimensions == 3) {
else if (t->Target == GL_TEXTURE_3D) {
/* Test 3-D mipmaps */
GLuint width = t->Image[baseLevel]->Width2;
GLuint height = t->Image[baseLevel]->Height2;
@@ -386,7 +408,7 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
}
}
else if (t->Dimensions == 6) {
else if (t->Target == GL_TEXTURE_CUBE_MAP_ARB) {
/* make sure 6 cube faces are consistant */
GLuint width = t->Image[baseLevel]->Width2;
GLuint height = t->Image[baseLevel]->Height2;
@@ -428,8 +450,12 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
}
}
}
else if (t->Target == GL_TEXTURE_RECTANGLE_NV) {
/* XXX special checking? */
}
else {
/* Dimensions = ??? */
/* Target = ??? */
_mesa_problem(ctx, "Bug in gl_test_texture_object_completeness\n");
}
}
@@ -473,8 +499,8 @@ _mesa_GenTextures( GLsizei n, GLuint *texName )
/* Allocate new, empty texture objects */
for (i=0;i<n;i++) {
GLuint name = first + i;
GLuint dims = 0;
(void) _mesa_alloc_texture_object( ctx->Shared, name, dims);
GLenum target = 0;
(void) _mesa_alloc_texture_object( ctx->Shared, name, target);
}
_glthread_UNLOCK_MUTEX(GenTexturesLock);
@@ -561,7 +587,6 @@ _mesa_BindTexture( GLenum target, GLuint texName )
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *oldTexObj;
struct gl_texture_object *newTexObj = 0;
GLuint targetDim;
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
@@ -570,24 +595,28 @@ _mesa_BindTexture( GLenum target, GLuint texName )
switch (target) {
case GL_TEXTURE_1D:
targetDim = 1;
oldTexObj = texUnit->Current1D;
break;
case GL_TEXTURE_2D:
targetDim = 2;
oldTexObj = texUnit->Current2D;
break;
case GL_TEXTURE_3D:
targetDim = 3;
oldTexObj = texUnit->Current3D;
break;
case GL_TEXTURE_CUBE_MAP_ARB:
if (ctx->Extensions.ARB_texture_cube_map) {
targetDim = 6;
oldTexObj = texUnit->CurrentCubeMap;
break;
if (!ctx->Extensions.ARB_texture_cube_map) {
_mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
return;
}
/* fallthrough */
oldTexObj = texUnit->CurrentCubeMap;
break;
case GL_TEXTURE_RECTANGLE_NV:
if (!ctx->Extensions.NV_texture_rectangle) {
_mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
return;
}
oldTexObj = texUnit->CurrentRect;
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glBindTexture(target)" );
return;
@@ -614,6 +643,9 @@ _mesa_BindTexture( GLenum target, GLuint texName )
case GL_TEXTURE_CUBE_MAP_ARB:
newTexObj = ctx->Shared->DefaultCubeMap;
break;
case GL_TEXTURE_RECTANGLE_NV:
newTexObj = ctx->Shared->DefaultRect;
break;
default:
; /* Bad targets are caught above */
}
@@ -624,23 +656,30 @@ _mesa_BindTexture( GLenum target, GLuint texName )
newTexObj = (struct gl_texture_object *) _mesa_HashLookup(hash, texName);
if (newTexObj) {
/* error checking */
if (newTexObj->Dimensions > 0 && newTexObj->Dimensions != targetDim) {
if (newTexObj->Target != 0 && newTexObj->Target != target) {
/* the named texture object's dimensions don't match the target */
_mesa_error( ctx, GL_INVALID_OPERATION,
"glBindTexture(wrong dimensionality)" );
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;
}
}
else {
/* if this is a new texture id, allocate a texture object now */
newTexObj = _mesa_alloc_texture_object( ctx->Shared, texName,
targetDim);
target);
if (!newTexObj) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindTexture");
return;
}
}
newTexObj->Dimensions = targetDim;
newTexObj->Target = target;
}
newTexObj->RefCount++;
@@ -662,8 +701,12 @@ _mesa_BindTexture( GLenum target, GLuint texName )
case GL_TEXTURE_CUBE_MAP_ARB:
texUnit->CurrentCubeMap = newTexObj;
break;
case GL_TEXTURE_RECTANGLE_NV:
texUnit->CurrentRect = newTexObj;
break;
default:
_mesa_problem(ctx, "bad target in BindTexture");
return;
}
/* Pass BindTexture call to device driver */