X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fswrast%2Fs_texture.c;h=97a8447c3062d23970839f78386b24b55c201037;hb=f595212336ae63c981f0f39f4ea1dec67ff7fe25;hp=e1ba95841775cad60bf6073ea53ff0c4070b602c;hpb=636b2801d981872d3111be0cd11aa79b4cc8643b;p=mesa.git diff --git a/src/mesa/swrast/s_texture.c b/src/mesa/swrast/s_texture.c index e1ba9584177..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.57 2002/03/23 16:33:53 brianp Exp $ */ +/* $Id: s_texture.c,v 1.62 2002/05/02 00:59:20 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -2250,7 +2250,7 @@ sample_depth_texture( GLcontext *ctx, GLuint unit, result = 0; break; case GL_NEVER: - result = CHAN_MAXF; + result = CHAN_MAX; break; case GL_NONE: /* ordinary bilinear filtering */ @@ -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,20 +2543,38 @@ 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", + textureUnit->CombineModeRGB, + textureUnit->CombineModeA, + textureUnit->CombineSourceRGB[0], + textureUnit->CombineSourceA[0], + textureUnit->CombineSourceRGB[1], + textureUnit->CombineSourceA[1]); + */ /* * 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; @@ -2566,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; @@ -2597,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) { @@ -2689,7 +2733,7 @@ texture_combine(const GLcontext *ctx, const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; #if CHAN_TYPE != GL_FLOAT - const GLint shift = 8 - RGBshift; + const GLint shift = CHAN_BITS - RGBshift; #endif for (i = 0; i < n; i++) { #if CHAN_TYPE == GL_FLOAT @@ -2756,7 +2800,7 @@ texture_combine(const GLcontext *ctx, const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2]; #if CHAN_TYPE != GL_FLOAT - const GLint shift = 8 - RGBshift; + const GLint shift = CHAN_BITS - RGBshift; #endif for (i = 0; i < n; i++) { #if CHAN_TYPE == GL_FLOAT @@ -2803,15 +2847,37 @@ texture_combine(const GLcontext *ctx, } } break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + { + /* Do not scale the result by 1 2 or 4 */ + const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; + const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + for (i = 0; i < n; i++) { +#if CHAN_TYPE == GL_FLOAT + GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) + + (arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) + + (arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F)) + * 4.0F; +#else + GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half, + (GLint)arg1[i][RCOMP] - half) + + S_PROD((GLint)arg0[i][GCOMP] - half, + (GLint)arg1[i][GCOMP] - half) + + S_PROD((GLint)arg0[i][BCOMP] - half, + (GLint)arg1[i][BCOMP] - half)) >> 6; +#endif + dot = CLAMP(dot, 0, CHAN_MAX); + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; + } + } + break; case GL_DOT3_RGB_ARB: case GL_DOT3_RGBA_ARB: { + /* DO scale the result by 1 2 or 4 */ const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; - /* ATI's EXT extension has a constant scale by 4. The ARB - * one will likely remove this restriction, and we should - * drop the EXT extension in favour of the ARB one. - */ for (i = 0; i < n; i++) { #if CHAN_TYPE == GL_FLOAT GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) + @@ -2826,7 +2892,7 @@ texture_combine(const GLcontext *ctx, S_PROD((GLint)arg0[i][BCOMP] - half, (GLint)arg1[i][BCOMP] - half)) >> 6; #endif - dot = CLAMP(dot, 0, CHAN_MAX); + dot = CLAMP(dot, 0, CHAN_MAX) << RGBshift; rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; } } @@ -2861,7 +2927,7 @@ texture_combine(const GLcontext *ctx, const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; #if CHAN_TYPE != GL_FLOAT - const GLint shift = 8 - Ashift; + const GLint shift = CHAN_BITS - Ashift; #endif for (i = 0; i < n; i++) { #if CHAN_TYPE == GL_FLOAT @@ -2908,7 +2974,7 @@ texture_combine(const GLcontext *ctx, const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2]; #if CHAN_TYPE != GL_FLOAT - const GLint shift = 8 - Ashift; + const GLint shift = CHAN_BITS - Ashift; #endif for (i=0; iCombineModeRGB == GL_DOT3_RGBA_EXT || textureUnit->CombineModeRGB == GL_DOT3_RGBA_ARB) { @@ -2956,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 @@ -2973,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], @@ -3052,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; @@ -3118,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; @@ -3151,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; @@ -3221,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; @@ -3298,59 +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, GLuint n, - GLfloat texcoords[][4], GLfloat lambda[], - CONST GLchan primary_rgba[][4], - GLchan rgba[][4] ) +_swrast_texture_span( GLcontext *ctx, struct sw_span *span ) { - const GLuint mask = TEXTURE0_ANY << (texUnit * 4); - - if (ctx->Texture._ReallyEnabled & mask) { - const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit]; - - if (textureUnit->_Current) { /* XXX need this? */ - const struct gl_texture_object *curObj = textureUnit->_Current; - GLchan texel[MAX_WIDTH][4]; - - if (lambda) { -#if 0 - float min, max; - int i; - min = max = lambda[0]; - for (i = 1; i < n; 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) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLchan primary_rgba[MAX_WIDTH][4]; + GLuint unit; + + ASSERT(span->end < MAX_WIDTH); + ASSERT(span->arrayMask & SPAN_TEXTURE); + + /* + * 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)); + + /* + * 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 (texUnit->LodBias != 0.0F) { /* apply LOD bias, but don't clamp yet */ GLuint i; - for (i=0;iLodBias; + for (i = 0; i < span->end; i++) { + lambda[i] += texUnit->LodBias; } } @@ -3359,67 +3435,50 @@ _swrast_texture_fragments( GLcontext *ctx, GLuint texUnit, GLuint n, const GLfloat min = curObj->MinLod; const GLfloat max = curObj->MaxLod; GLuint i; - for (i=0;iend; 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, - n, texcoords, - lambda, texel ); - - apply_texture( ctx, textureUnit, n, primary_rgba, - (const GLchan (*)[4]) texel, 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); - - /* 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->end, - span->texcoords[unit], - (span->arrayMask & SPAN_LAMBDA) ? - span->lambda[unit] : NULL, - (CONST GLchan (*)[4]) primary_rgba, - span->color.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->end, - span->texcoords[0], - (span->arrayMask & SPAN_LAMBDA) ? - span->lambda[0] : NULL, - (CONST GLchan (*)[4]) span->color.rgba, - span->color.rgba ); - } }