From: Brian Paul Date: Thu, 2 May 2002 00:59:20 +0000 (+0000) Subject: Implemented GL_ARB_texture_env_crossbar. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f595212336ae63c981f0f39f4ea1dec67ff7fe25;p=mesa.git Implemented GL_ARB_texture_env_crossbar. Simplification of some of the texture application code. --- diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index fe43e668386..96984359c18 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -1,4 +1,4 @@ -/* $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 @@ -68,6 +68,7 @@ static struct { { 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 }, @@ -150,6 +151,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) "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", diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 28a1921edd4..41ba77ba92c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1,4 +1,4 @@ -/* $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 @@ -1389,6 +1389,7 @@ struct gl_extensions { 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; diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index 88618c67ff2..67cb4022dc1 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -1,4 +1,4 @@ -/* $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 @@ -77,51 +77,42 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 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) { @@ -172,28 +163,23 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 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); @@ -205,19 +191,22 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 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; } @@ -232,18 +221,22 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 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; } @@ -257,8 +250,8 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 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: @@ -283,7 +276,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 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: @@ -306,7 +299,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 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 */ @@ -329,7 +322,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) 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 */ @@ -1261,6 +1254,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, 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)"); diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 96572aa0634..809ee681223 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -1,4 +1,4 @@ -/* $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 @@ -40,9 +40,6 @@ #include "s_texture.h" - - - /* * Recompute the value of swrast->_RasterMask, etc. according to * the current context. @@ -145,6 +142,26 @@ _swrast_update_hint( GLcontext *ctx ) 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 | \ @@ -183,6 +200,8 @@ _swrast_update_hint( GLcontext *ctx ) #define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE +#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE + #define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR @@ -315,7 +334,6 @@ _swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) 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); @@ -334,18 +352,15 @@ _swrast_invalidate_state( GLcontext *ctx, GLuint new_state ) 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 ); @@ -355,6 +370,9 @@ _swrast_validate_derived( GLcontext *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; @@ -490,7 +508,6 @@ _swrast_CreateContext( GLcontext *ctx ) swrast->_IntegerAccumMode = GL_TRUE; swrast->_IntegerAccumScaler = 0.0; - for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) swrast->TextureSample[i] = _swrast_validate_texture_sample; @@ -499,7 +516,18 @@ _swrast_CreateContext( GLcontext *ctx ) 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; @@ -515,7 +543,7 @@ _swrast_DestroyContext( GLcontext *ctx ) } FREE( swrast->span ); - + FREE( swrast->TexelBuffer ); FREE( swrast ); ctx->swrast_context = 0; diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index b0ca5bf1b57..900c1907f60 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -1,4 +1,4 @@ -/* $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 @@ -124,6 +124,7 @@ typedef struct GLfloat _MinMagThresh[MAX_TEXTURE_UNITS]; GLfloat _backface_sign; GLboolean _PreferPixelFog; + GLboolean _AnyTextureCombine; /* Accum buffer temporaries. */ @@ -176,6 +177,11 @@ typedef struct 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; diff --git a/src/mesa/swrast/s_pixeltex.c b/src/mesa/swrast/s_pixeltex.c index c2b597a9afd..3afda84fa0e 100644 --- a/src/mesa/swrast/s_pixeltex.c +++ b/src/mesa/swrast/s_pixeltex.c @@ -1,4 +1,4 @@ -/* $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 @@ -85,47 +85,34 @@ pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4], /* - * 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; } diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 9712efb919e..1e3c710b8a1 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,4 +1,4 @@ -/* $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 @@ -1171,7 +1171,7 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *span) /* 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)) { @@ -1220,7 +1220,7 @@ _mesa_write_texture_span( GLcontext *ctx, struct sw_span *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); diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c index 44738acdad5..97a8447c306 100644 --- a/src/mesa/swrast/s_texture.c +++ b/src/mesa/swrast/s_texture.c @@ -1,4 +1,4 @@ -/* $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 @@ -2394,6 +2394,9 @@ sample_depth_texture2(const GLcontext *ctx, #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, @@ -2404,12 +2407,7 @@ null_sample_func( GLcontext *ctx, GLuint texUnit, -/**********************************************************************/ -/* Texture Sampling Setup */ -/**********************************************************************/ - - -/* +/** * Setup the texture sampling function for this texture object. */ void @@ -2516,17 +2514,27 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit, #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 @@ -2535,12 +2543,16 @@ texture_combine(const GLcontext *ctx, #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", @@ -2556,9 +2568,13 @@ texture_combine(const GLcontext *ctx, * 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; @@ -2576,12 +2592,21 @@ texture_combine(const GLcontext *ctx, } 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; @@ -2607,7 +2632,16 @@ texture_combine(const GLcontext *ctx, } 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) { @@ -2991,14 +3025,23 @@ texture_combine(const GLcontext *ctx, #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 @@ -3008,7 +3051,7 @@ texture_combine(const GLcontext *ctx, * 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], @@ -3087,7 +3130,7 @@ apply_texture( const GLcontext *ctx, } break; default: - _mesa_problem(ctx, "Bad format (GL_REPLACE) in apply_texture"); + _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply"); return; } break; @@ -3153,7 +3196,7 @@ apply_texture( const GLcontext *ctx, } break; default: - _mesa_problem(ctx, "Bad format (GL_MODULATE) in apply_texture"); + _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply"); return; } break; @@ -3186,7 +3229,7 @@ apply_texture( const GLcontext *ctx, } break; default: - _mesa_problem(ctx, "Bad format (GL_DECAL) in apply_texture"); + _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply"); return; } break; @@ -3256,7 +3299,7 @@ apply_texture( const GLcontext *ctx, } break; default: - _mesa_problem(ctx, "Bad format (GL_BLEND) in apply_texture"); + _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply"); return; } break; @@ -3333,63 +3376,57 @@ apply_texture( const GLcontext *ctx, } 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;iend;i++) { - lambda[i] += textureUnit->LodBias; + for (i = 0; i < span->end; i++) { + lambda[i] += texUnit->LodBias; } } @@ -3398,60 +3435,50 @@ _swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, const GLfloat min = curObj->MinLod; const GLfloat max = curObj->MaxLod; GLuint i; - for (i=0;iend;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); - } } diff --git a/src/mesa/swrast/s_texture.h b/src/mesa/swrast/s_texture.h index 91f147afe02..a920c0fb7c0 100644 --- a/src/mesa/swrast/s_texture.h +++ b/src/mesa/swrast/s_texture.h @@ -1,4 +1,4 @@ -/* $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 @@ -40,12 +40,6 @@ _swrast_choose_texture_sample_func( GLcontext *ctx, 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