Simplification of some of the texture application code.
-/* $Id: extensions.c,v 1.72 2002/04/02 16:15:17 brianp Exp $ */
+/* $Id: extensions.c,v 1.73 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
{ OFF, "GL_ARB_texture_cube_map", F(ARB_texture_cube_map) },
{ OFF, "GL_ARB_texture_env_add", F(EXT_texture_env_add) },
{ OFF, "GL_ARB_texture_env_combine", F(ARB_texture_env_combine) },
+ { OFF, "GL_ARB_texture_env_crossbar", F(ARB_texture_env_crossbar) },
{ OFF, "GL_ARB_texture_env_dot3", F(ARB_texture_env_dot3) },
{ OFF, "GL_ARB_texture_mirrored_repeat", F(ARB_texture_mirrored_repeat)},
{ ON, "GL_ARB_transpose_matrix", 0 },
"GL_ARB_texture_cube_map",
"GL_ARB_texture_env_add",
"GL_ARB_texture_env_combine",
+ "GL_ARB_texture_env_crossbar",
"GL_ARB_texture_env_dot3",
"GL_ARB_texture_mirrored_repeat",
"GL_EXT_blend_color",
-/* $Id: mtypes.h,v 1.73 2002/04/21 20:37:04 brianp Exp $ */
+/* $Id: mtypes.h,v 1.74 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
GLboolean ARB_texture_compression;
GLboolean ARB_texture_cube_map;
GLboolean ARB_texture_env_combine;
+ GLboolean ARB_texture_env_crossbar;
GLboolean ARB_texture_env_dot3;
GLboolean ARB_texture_mirrored_repeat;
GLboolean ARB_window_pos;
-/* $Id: texstate.c,v 1.70 2002/04/26 13:40:11 brianp Exp $ */
+/* $Id: texstate.c,v 1.71 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
if (target==GL_TEXTURE_ENV) {
switch (pname) {
- case GL_TEXTURE_ENV_MODE: {
- GLenum mode = (GLenum) (GLint) *param;
-
- switch (mode) {
- case GL_ADD:
- if (!ctx->Extensions.EXT_texture_env_add) {
- TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
- return;
- }
- break;
- case GL_COMBINE_EXT:
- if (!ctx->Extensions.EXT_texture_env_combine &&
- !ctx->Extensions.ARB_texture_env_combine) {
- TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
- return;
- }
- break;
- case GL_MODULATE:
- case GL_BLEND:
- case GL_DECAL:
- case GL_REPLACE:
- break;
- default:
- TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
- return;
- }
-
- if (texUnit->EnvMode == mode)
- return;
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- texUnit->EnvMode = mode;
- break;
- }
- case GL_TEXTURE_ENV_COLOR: {
- GLfloat tmp[4];
- tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
- tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
- tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
- tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
- if (TEST_EQ_4V(tmp, texUnit->EnvColor))
- return;
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- COPY_4FV(texUnit->EnvColor, tmp);
- break;
- }
+ case GL_TEXTURE_ENV_MODE:
+ {
+ const GLenum mode = (GLenum) (GLint) *param;
+ if (mode == GL_MODULATE ||
+ mode == GL_BLEND ||
+ mode == GL_DECAL ||
+ mode == GL_REPLACE ||
+ (mode == GL_ADD && ctx->Extensions.EXT_texture_env_add) ||
+ (mode == GL_COMBINE_EXT &&
+ (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;
+ }
+ else {
+ TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ return;
+ }
+ }
+ break;
+ case GL_TEXTURE_ENV_COLOR:
+ {
+ GLfloat tmp[4];
+ tmp[0] = CLAMP( param[0], 0.0F, 1.0F );
+ tmp[1] = CLAMP( param[1], 0.0F, 1.0F );
+ tmp[2] = CLAMP( param[2], 0.0F, 1.0F );
+ tmp[3] = CLAMP( param[3], 0.0F, 1.0F );
+ if (TEST_EQ_4V(tmp, texUnit->EnvColor))
+ return;
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ COPY_4FV(texUnit->EnvColor, tmp);
+ }
+ break;
case GL_COMBINE_RGB_EXT:
if (ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine) {
if (ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine) {
const GLenum mode = (GLenum) (GLint) *param;
- switch (mode) {
- case GL_REPLACE:
- case GL_MODULATE:
- case GL_ADD:
- case GL_ADD_SIGNED_EXT:
- case GL_INTERPOLATE_EXT:
- /* OK */
- break;
- case GL_SUBTRACT_ARB:
- if (!ctx->Extensions.ARB_texture_env_combine) {
- TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
+ if (mode == GL_REPLACE ||
+ mode == GL_MODULATE ||
+ mode == GL_ADD ||
+ mode == GL_ADD_SIGNED_EXT ||
+ mode == GL_INTERPOLATE_EXT ||
+ (mode == GL_SUBTRACT_ARB &&
+ ctx->Extensions.ARB_texture_env_combine)) {
+ /* legal */
+ if (texUnit->CombineModeA == mode)
return;
- }
- break;
- default:
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ texUnit->CombineModeA = mode;
+ }
+ else {
TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", mode);
return;
}
- if (texUnit->CombineModeA == mode)
- return;
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
- texUnit->CombineModeA = mode;
}
else {
TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname);
case GL_SOURCE2_RGB_EXT:
if (ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine) {
- GLenum source = (GLenum) (GLint) *param;
- GLuint s = pname - GL_SOURCE0_RGB_EXT;
- switch (source) {
- case GL_TEXTURE:
- case GL_CONSTANT_EXT:
- case GL_PRIMARY_COLOR_EXT:
- case GL_PREVIOUS_EXT:
- if (texUnit->CombineSourceRGB[s] == source)
- return;
+ const GLenum source = (GLenum) (GLint) *param;
+ const GLuint s = pname - GL_SOURCE0_RGB_EXT;
+ if (source == GL_TEXTURE ||
+ source == GL_CONSTANT_EXT ||
+ source == GL_PRIMARY_COLOR_EXT ||
+ source == GL_PREVIOUS_EXT ||
+ (ctx->Extensions.ARB_texture_env_crossbar &&
+ source >= GL_TEXTURE0_ARB &&
+ source < GL_TEXTURE0_ARB + ctx->Const.MaxTextureUnits)) {
+ /* legal */
+ if (texUnit->CombineSourceRGB[s] == source)
+ return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->CombineSourceRGB[s] = source;
- break;
- default:
+ }
+ else {
TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
return;
}
case GL_SOURCE2_ALPHA_EXT:
if (ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine) {
- GLenum source = (GLenum) (GLint) *param;
- GLuint s = pname - GL_SOURCE0_ALPHA_EXT;
- switch (source) {
- case GL_TEXTURE:
- case GL_CONSTANT_EXT:
- case GL_PRIMARY_COLOR_EXT:
- case GL_PREVIOUS_EXT:
- if (texUnit->CombineSourceA[s] == source) return;
+ const GLenum source = (GLenum) (GLint) *param;
+ const GLuint s = pname - GL_SOURCE0_ALPHA_EXT;
+ if (source == GL_TEXTURE ||
+ source == GL_CONSTANT_EXT ||
+ source == GL_PRIMARY_COLOR_EXT ||
+ source == GL_PREVIOUS_EXT ||
+ (ctx->Extensions.ARB_texture_env_crossbar &&
+ source >= GL_TEXTURE0_ARB &&
+ source < GL_TEXTURE0_ARB + ctx->Const.MaxTextureUnits)) {
+ /* legal */
+ if (texUnit->CombineSourceA[s] == source)
+ return;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
texUnit->CombineSourceA[s] = source;
- break;
- default:
+ }
+ else {
TE_ERROR(GL_INVALID_ENUM, "glTexEnv(param=%s)", source);
return;
}
case GL_OPERAND1_RGB_EXT:
if (ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine) {
- GLenum operand = (GLenum) (GLint) *param;
- GLuint s = pname - GL_OPERAND0_RGB_EXT;
+ const GLenum operand = (GLenum) (GLint) *param;
+ const GLuint s = pname - GL_OPERAND0_RGB_EXT;
switch (operand) {
case GL_SRC_COLOR:
case GL_ONE_MINUS_SRC_COLOR:
case GL_OPERAND1_ALPHA_EXT:
if (ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine) {
- GLenum operand = (GLenum) (GLint) *param;
+ const GLenum operand = (GLenum) (GLint) *param;
switch (operand) {
case GL_SRC_ALPHA:
case GL_ONE_MINUS_SRC_ALPHA:
case GL_OPERAND2_RGB_EXT:
if (ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine) {
- GLenum operand = (GLenum) (GLint) *param;
+ const GLenum operand = (GLenum) (GLint) *param;
switch (operand) {
case GL_SRC_COLOR: /* ARB combine only */
case GL_ONE_MINUS_SRC_COLOR: /* ARB combine only */
case GL_OPERAND2_ALPHA_EXT:
if (ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine) {
- GLenum operand = (GLenum) (GLint) *param;
+ const GLenum operand = (GLenum) (GLint) *param;
switch (operand) {
case GL_SRC_ALPHA:
case GL_ONE_MINUS_SRC_ALPHA: /* ARB combine only */
GLint maxLevels;
ASSERT_OUTSIDE_BEGIN_END(ctx);
+ /* this will catch bad target values */
dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
if (dimensions == 0) {
_mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
-/* $Id: s_context.c,v 1.31 2002/04/19 14:05:50 brianp Exp $ */
+/* $Id: s_context.c,v 1.32 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
#include "s_texture.h"
-
-
-
/*
* Recompute the value of swrast->_RasterMask, etc. according to
* the current context.
swrast->AllowPixelFog));
}
+
+/*
+ * Update the swrast->_AnyTextureCombine flag.
+ */
+static void
+_swrast_update_texture_env( GLcontext *ctx )
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLuint i;
+ swrast->_AnyTextureCombine = GL_FALSE;
+ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+ if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT ||
+ ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) {
+ swrast->_AnyTextureCombine = GL_TRUE;
+ return;
+ }
+ }
+}
+
+
#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \
_NEW_TEXTURE | \
_NEW_HINT | \
#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
+#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
+
#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
swrast->TextureSample[i] = _swrast_validate_texture_sample;
-
if (ctx->Visual.rgbMode) {
ASSERT(swrast->Driver.WriteRGBASpan);
ASSERT(swrast->Driver.WriteRGBSpan);
ASSERT(swrast->Driver.ReadCI32Span);
ASSERT(swrast->Driver.ReadCI32Pixels);
}
-
}
-
void
_swrast_validate_derived( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- if (swrast->NewState)
- {
+ if (swrast->NewState) {
if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
_swrast_update_rasterflags( ctx );
if (swrast->NewState & _NEW_HINT)
_swrast_update_hint( ctx );
+ if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE)
+ _swrast_update_texture_env( ctx );
+
swrast->NewState = 0;
swrast->StateChanges = 0;
swrast->InvalidateState = _swrast_invalidate_state;
swrast->_IntegerAccumMode = GL_TRUE;
swrast->_IntegerAccumScaler = 0.0;
-
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
swrast->TextureSample[i] = _swrast_validate_texture_sample;
FREE(swrast);
return GL_FALSE;
}
-
+
+ assert(ctx->Const.MaxTextureUnits > 0);
+ assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_UNITS);
+
+ swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureUnits *
+ MAX_WIDTH * 4 * sizeof(GLchan));
+ if (!swrast->TexelBuffer) {
+ FREE(swrast->span);
+ FREE(swrast);
+ return GL_FALSE;
+ }
+
ctx->swrast_context = swrast;
return GL_TRUE;
}
FREE( swrast->span );
-
+ FREE( swrast->TexelBuffer );
FREE( swrast );
ctx->swrast_context = 0;
-/* $Id: s_context.h,v 1.17 2002/04/19 14:05:50 brianp Exp $ */
+/* $Id: s_context.h,v 1.18 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
GLfloat _MinMagThresh[MAX_TEXTURE_UNITS];
GLfloat _backface_sign;
GLboolean _PreferPixelFog;
+ GLboolean _AnyTextureCombine;
/* Accum buffer temporaries.
*/
blend_func BlendFunc;
TextureSampleFunc TextureSample[MAX_TEXTURE_UNITS];
+ /** Buffer for saving the sampled texture colors.
+ * Needed for GL_ARB_texture_env_crossbar implementation.
+ */
+ GLchan *TexelBuffer;
+
} SWcontext;
-/* $Id: s_pixeltex.c,v 1.8 2002/04/12 15:39:59 brianp Exp $ */
+/* $Id: s_pixeltex.c,v 1.9 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
/*
- * Used byglDraw/CopyPixels: the incoming image colors are treated
+ * Used by glDraw/CopyPixels: the incoming image colors are treated
* as texture coordinates. Use those coords to texture the image.
* This is for GL_SGIS_pixel_texture / GL_SGIX_pixel_texture.
*/
void
_swrast_pixel_texture(GLcontext *ctx, struct sw_span *span)
{
- if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
- /* multitexture! */
- GLchan primary_rgba[MAX_WIDTH][4];
- GLuint unit;
-
- ASSERT(!(span->arrayMask & SPAN_TEXTURE));
- span->arrayMask |= SPAN_TEXTURE;
-
- MEMCPY(primary_rgba, span->color.rgba, 4 * span->end * sizeof(GLchan));
-
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- pixeltexgen(ctx, span->end,
- (const GLchan (*)[4]) span->color.rgba,
- span->texcoords[unit]);
- _swrast_texture_fragments(ctx, unit, span,
- (CONST GLchan (*)[4]) primary_rgba);
- }
+ GLuint unit;
+
+ ASSERT(!(span->arrayMask & SPAN_TEXTURE));
+ span->arrayMask |= SPAN_TEXTURE;
+
+ /* convert colors into texture coordinates */
+ pixeltexgen( ctx, span->end,
+ (const GLchan (*)[4]) span->color.rgba,
+ span->texcoords[0] );
+
+ /* copy the new texture units for all enabled units */
+ for (unit = 1; unit < ctx->Const.MaxTextureUnits; unit++) {
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ MEMCPY( span->texcoords[unit], span->texcoords[0],
+ span->end * 4 * sizeof(GLfloat) );
}
- /* this is a work-around to be fixed by initializing again span */
- span->arrayMask &= ~SPAN_TEXTURE;
- }
- else {
- /* single texture, unit 0 */
- ASSERT(ctx->Texture._ReallyEnabled & TEXTURE0_ANY);
- ASSERT(!(span->arrayMask & SPAN_TEXTURE));
- span->arrayMask |= SPAN_TEXTURE;
-
- pixeltexgen(ctx, span->end,
- (const GLchan (*)[4]) span->color.rgba,
- span->texcoords[0]);
- _swrast_texture_fragments(ctx, 0, span,
- (CONST GLchan (*)[4]) span->color.rgba);
- /* this is a work-around to be fixed */
- span->arrayMask &= ~SPAN_TEXTURE;
}
+
+ /* apply texture mapping */
+ _swrast_texture_span( ctx, span );
+
+ /* this is a work-around to be fixed by initializing again span */
+ span->arrayMask &= ~SPAN_TEXTURE;
}
-/* $Id: s_span.c,v 1.41 2002/04/20 17:54:55 brianp Exp $ */
+/* $Id: s_span.c,v 1.42 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
/* Texturing without alpha is done after depth-testing which
* gives a potential speed-up.
*/
- _swrast_multitexture_fragments( ctx, span );
+ _swrast_texture_span( ctx, span );
/* Do the alpha test */
if (!_mesa_alpha_test(ctx, span)) {
if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
interpolate_colors(ctx, span);
- _swrast_multitexture_fragments( ctx, span );
+ _swrast_texture_span( ctx, span );
}
ASSERT(span->arrayMask & SPAN_RGBA);
-/* $Id: s_texture.c,v 1.61 2002/04/19 00:38:27 brianp Exp $ */
+/* $Id: s_texture.c,v 1.62 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
#endif
+/**
+ * We use this function when a texture object is in an "incomplete" state.
+ */
static void
null_sample_func( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
-/**********************************************************************/
-/* Texture Sampling Setup */
-/**********************************************************************/
-
-
-/*
+/**
* Setup the texture sampling function for this texture object.
*/
void
#define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) )
#define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
+
+/**
+ * Do texture application for GL_ARB/EXT_texture_env_combine.
+ * Input:
+ * ctx - rendering context
+ * textureUnit - the texture unit to apply
+ * n - number of fragments to process (span width)
+ * primary_rgba - incoming fragment color array
+ * texelBuffer - pointer to texel colors for all texture units
+ * Input/Output:
+ * rgba - incoming colors, which get modified here
+ */
static INLINE void
-texture_combine(const GLcontext *ctx,
- const struct gl_texture_unit *textureUnit,
- GLuint n,
- CONST GLchan (*primary_rgba)[4],
- CONST GLchan (*texel)[4],
- GLchan (*rgba)[4])
+texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
+ CONST GLchan (*primary_rgba)[4],
+ CONST GLchan *texelBuffer,
+ GLchan (*rgba)[4] )
{
+ const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
const GLchan (*argRGB [3])[4];
const GLchan (*argA [3])[4];
- GLuint i, j;
const GLuint RGBshift = textureUnit->CombineScaleShiftRGB;
const GLuint Ashift = textureUnit->CombineScaleShiftA;
#if CHAN_TYPE == GL_FLOAT
#else
const GLint half = (CHAN_MAX + 1) / 2;
#endif
+ GLuint i, j;
+ /* GLchan ccolor[3][4]; */
DEFMNARRAY(GLchan, ccolor, 3, 3 * MAX_WIDTH, 4); /* mac 32k limitation */
CHECKARRAY(ccolor, return); /* mac 32k limitation */
ASSERT(ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine);
+ ASSERT(SWRAST_CONTEXT(ctx)->_AnyTextureCombine);
+
/*
printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n",
* Do operand setup for up to 3 operands. Loop over the terms.
*/
for (j = 0; j < 3; j++) {
- switch (textureUnit->CombineSourceA[j]) {
+ const GLenum srcA = textureUnit->CombineSourceA[j];
+ const GLenum srcRGB = textureUnit->CombineSourceRGB[j];
+
+ switch (srcA) {
case GL_TEXTURE:
- argA[j] = texel;
+ argA[j] = (const GLchan (*)[4])
+ (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
break;
case GL_PRIMARY_COLOR_EXT:
argA[j] = primary_rgba;
}
break;
default:
- _mesa_problem(ctx, "invalid combine source");
+ /* ARB_texture_env_crossbar source */
+ {
+ const GLuint srcUnit = srcA - GL_TEXTURE0_ARB;
+ ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
+ if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
+ return;
+ argA[j] = (const GLchan (*)[4])
+ (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
+ }
}
- switch (textureUnit->CombineSourceRGB[j]) {
+ switch (srcRGB) {
case GL_TEXTURE:
- argRGB[j] = texel;
+ argRGB[j] = (const GLchan (*)[4])
+ (texelBuffer + unit * (n * 4 * sizeof(GLchan)));
break;
case GL_PRIMARY_COLOR_EXT:
argRGB[j] = primary_rgba;
}
break;
default:
- _mesa_problem(ctx, "invalid combine source");
+ /* ARB_texture_env_crossbar source */
+ {
+ const GLuint srcUnit = srcRGB - GL_TEXTURE0_ARB;
+ ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
+ if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
+ return;
+ argRGB[j] = (const GLchan (*)[4])
+ (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
+ printf("unit %d from unit %d\n", unit, srcUnit);
+ }
}
if (textureUnit->CombineOperandRGB[j] != GL_SRC_COLOR) {
#undef PROD
+/**
+ * Implement NVIDIA's GL_NV_texture_env_combine4 extension when
+ * texUnit->EnvMode == GL_COMBINE4_NV.
+ */
+static INLINE void
+texture_combine4( const GLcontext *ctx, GLuint unit, GLuint n,
+ CONST GLchan (*primary_rgba)[4],
+ CONST GLchan *texelBuffer,
+ GLchan (*rgba)[4] )
+{
+}
-/**********************************************************************/
-/* Texture Application */
-/**********************************************************************/
-/*
- * Combine incoming fragment color with texel color to produce output color.
+/**
+ * Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
+ * MODULATE, or DECAL) to an array of fragments.
* Input: textureUnit - pointer to texture unit to apply
* format - base internal texture format
* n - number of fragments
* according to the texture environment mode.
*/
static void
-apply_texture( const GLcontext *ctx,
+texture_apply( const GLcontext *ctx,
const struct gl_texture_unit *texUnit,
GLuint n,
CONST GLchan primary_rgba[][4], CONST GLchan texel[][4],
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_REPLACE) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply");
return;
}
break;
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_MODULATE) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply");
return;
}
break;
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_DECAL) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply");
return;
}
break;
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_BLEND) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply");
return;
}
break;
}
break;
default:
- _mesa_problem(ctx, "Bad format (GL_ADD) in apply_texture");
+ _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply");
return;
}
break;
- case GL_COMBINE_EXT:
- texture_combine(ctx, texUnit, n, primary_rgba, texel, rgba);
- break;
-
default:
- _mesa_problem(ctx, "Bad env mode in apply_texture");
+ _mesa_problem(ctx, "Bad env mode in texture_apply");
return;
}
}
-/*
- * Apply a unit of texture mapping to the incoming fragments.
+/**
+ * Apply texture mapping to a span of fragments.
*/
void
-_swrast_texture_fragments( GLcontext *ctx, GLuint texUnit,
- struct sw_span *span,
- CONST GLchan primary_rgba[][4])
+_swrast_texture_span( GLcontext *ctx, struct sw_span *span )
{
- const GLuint mask = TEXTURE0_ANY << (texUnit * 4);
- GLfloat (*texcoords)[4] = span->texcoords[texUnit];
- GLfloat *lambda = span->lambda[texUnit];
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ GLchan primary_rgba[MAX_WIDTH][4];
+ GLuint unit;
+ ASSERT(span->end < MAX_WIDTH);
+ ASSERT(span->arrayMask & SPAN_TEXTURE);
- if (ctx->Texture._ReallyEnabled & mask) {
- const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
+ /*
+ * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
+ */
+ if (swrast->_AnyTextureCombine)
+ MEMCPY(primary_rgba, span->color.rgba, 4 * span->end * sizeof(GLchan));
- ASSERT(span->arrayMask & SPAN_TEXTURE);
-
- if (textureUnit->_Current) { /* XXX need this? */
- const struct gl_texture_object *curObj = textureUnit->_Current;
- GLchan texel[MAX_WIDTH][4];
-
+ /*
+ * Must do all texture sampling before combining in order to
+ * accomodate GL_ARB_texture_env_crossbar.
+ */
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ const struct gl_texture_object *curObj = texUnit->_Current;
+ GLfloat *lambda = span->lambda[unit];
+ GLchan (*texels)[4] = (GLchan (*)[4])
+ (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan)));
+
+ /* adjust texture lod (lambda) */
if (span->arrayMask | SPAN_LAMBDA) {
-#if 0
- float min, max;
- int i;
- min = max = lambda[0];
- for (i = 1; i < span->end; i++) {
- if (lambda[i] > max)
- max = lambda[i];
- if (lambda[i] < min)
- min = lambda[i];
- }
- printf("min/max %g / %g\n", min, max);
-#endif
- if (textureUnit->LodBias != 0.0F) {
+ if (texUnit->LodBias != 0.0F) {
/* apply LOD bias, but don't clamp yet */
GLuint i;
- for (i=0;i<span->end;i++) {
- lambda[i] += textureUnit->LodBias;
+ for (i = 0; i < span->end; i++) {
+ lambda[i] += texUnit->LodBias;
}
}
const GLfloat min = curObj->MinLod;
const GLfloat max = curObj->MaxLod;
GLuint i;
- for (i=0;i<span->end;i++) {
+ for (i = 0; i < span->end; i++) {
GLfloat l = lambda[i];
lambda[i] = CLAMP(l, min, max);
}
}
}
- /* Sample the texture for n fragments */
- SWRAST_CONTEXT(ctx)->TextureSample[texUnit]( ctx, texUnit,
- textureUnit->_Current,
- span->end, texcoords,
- lambda, texel );
-
- apply_texture( ctx, textureUnit, span->end, primary_rgba,
- (const GLchan (*)[4]) texel, span->color.rgba );
+ /* Sample the texture (span->end fragments) */
+ swrast->TextureSample[unit]( ctx, unit, texUnit->_Current,
+ span->end, span->texcoords[unit],
+ lambda, texels );
}
}
-}
-
-/*
- * Apply multiple texture stages (or just unit 0) to the span.
- * At some point in the future we'll probably modify this so that
- * texels from any texture unit are available in any combiner unit.
- * That'll require doing all the texture sampling first, and then
- * all the application (blending) afterward.
- */
-void
-_swrast_multitexture_fragments( GLcontext *ctx, struct sw_span *span )
-{
- if (ctx->Texture._ReallyEnabled & ~TEXTURE0_ANY) {
- /* multitexture */
- GLchan primary_rgba[MAX_WIDTH][4];
- GLuint unit;
-
- ASSERT(span->end < MAX_WIDTH);
- ASSERT(span->arrayMask & SPAN_TEXTURE);
-
- /* save copy of the span colors (the GL_PRIMARY_COLOR) */
- MEMCPY(primary_rgba, span->color.rgba, 4 * span->end * sizeof(GLchan));
-
- /* loop over texture units, modifying the span->color.rgba values */
- for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
- if (ctx->Texture.Unit[unit]._ReallyEnabled) {
- _swrast_texture_fragments( ctx, unit, span,
- (CONST GLchan (*)[4]) primary_rgba);
+ /*
+ * OK, now apply the texture (aka texture combine/blend).
+ * We modify the span->color.rgba values.
+ */
+ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ if (texUnit->EnvMode == GL_COMBINE_EXT) {
+ /* GL_ARB/EXT_texture_env_combine */
+ texture_combine( ctx, unit, span->end,
+ (CONST GLchan (*)[4]) primary_rgba,
+ swrast->TexelBuffer,
+ span->color.rgba );
+ }
+ else if (texUnit->EnvMode == GL_COMBINE4_NV) {
+ /* GL_NV_texture_env_combine4 */
+ texture_combine4( ctx, unit, span->end,
+ (CONST GLchan (*)[4]) primary_rgba,
+ swrast->TexelBuffer,
+ span->color.rgba );
+ }
+ else {
+ /* conventional texture blend */
+ const GLchan (*texels)[4] = (const GLchan (*)[4])
+ (swrast->TexelBuffer + unit *
+ (span->end * 4 * sizeof(GLchan)));
+ texture_apply( ctx, texUnit, span->end,
+ (CONST GLchan (*)[4]) primary_rgba, texels,
+ span->color.rgba );
}
}
}
- else {
- /* Just unit 0 enabled */
- ASSERT(ctx->Texture._ReallyEnabled & TEXTURE0_ANY);
-
- _swrast_texture_fragments( ctx, 0, span,
- (CONST GLchan (*)[4]) span->color.rgba);
- }
}
-/* $Id: s_texture.h,v 1.12 2002/04/12 15:39:59 brianp Exp $ */
+/* $Id: s_texture.h,v 1.13 2002/05/02 00:59:20 brianp Exp $ */
/*
* Mesa 3-D graphics library
extern void
-_swrast_texture_fragments( GLcontext *ctx, GLuint texUnit,
- struct sw_span *span,
- CONST GLchan primary_rgba[][4]);
-
-
-extern void
-_swrast_multitexture_fragments( GLcontext *ctx, struct sw_span *span );
+_swrast_texture_span( GLcontext *ctx, struct sw_span *span );
#endif