diff options
author | Chia-I Wu <olvaffe@gmail.com> | 2009-09-15 14:16:22 +0800 |
---|---|---|
committer | Chia-I Wu <olvaffe@gmail.com> | 2009-09-15 14:16:22 +0800 |
commit | e2ba90a9cc762cf00a168f0a59d31e7dc52fc42e (patch) | |
tree | fe3206d7602ad935296884742980f3c4d30bd867 /src/mesa/swrast | |
parent | 11a4292d4eb515813b82b8d688a318adef66b3e6 (diff) | |
parent | b4b8800315637d9218a81c76f09df7d601710d29 (diff) |
Merge commit 'eee/mesa-es' into android
Diffstat (limited to 'src/mesa/swrast')
28 files changed, 1576 insertions, 2059 deletions
diff --git a/src/mesa/swrast/s_accum.c b/src/mesa/swrast/s_accum.c index ff741777e7..c29ccf2d9b 100644 --- a/src/mesa/swrast/s_accum.c +++ b/src/mesa/swrast/s_accum.c @@ -73,6 +73,9 @@ #endif +#if FEATURE_accum + + /** * This is called when we fall out of optimized/unscaled accum buffer mode. * That is, we convert each unscaled accum buffer value into a scaled value @@ -550,7 +553,7 @@ _swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value) SWcontext *swrast = SWRAST_CONTEXT(ctx); GLint xpos, ypos, width, height; - if (SWRAST_CONTEXT(ctx)->NewState) + if (swrast->NewState) _swrast_validate_derived( ctx ); if (!ctx->DrawBuffer->Attachment[BUFFER_ACCUM].Renderbuffer) { @@ -558,9 +561,9 @@ _swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value) return; } - RENDER_START(swrast, ctx); + swrast_render_start(ctx); - /* Compute region after calling RENDER_START so that we know the + /* Compute region after calling swrast_render_start() so that we know the * drawbuffer's size/bounds are up to date. */ xpos = ctx->DrawBuffer->_Xmin; @@ -595,5 +598,8 @@ _swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value) break; } - RENDER_FINISH(swrast, ctx); + swrast_render_finish(ctx); } + + +#endif /* FEATURE_accum */ diff --git a/src/mesa/swrast/s_accum.h b/src/mesa/swrast/s_accum.h index 42e38cf02b..730c0254b2 100644 --- a/src/mesa/swrast/s_accum.h +++ b/src/mesa/swrast/s_accum.h @@ -30,8 +30,19 @@ #include "main/mtypes.h" +#if FEATURE_accum + extern void _swrast_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb); +#else /* FEATURE_accum */ + +static INLINE void +_swrast_clear_accum_buffer(GLcontext *ctx, struct gl_renderbuffer *rb) +{ + ASSERT_NO_FEATURE(); +} #endif + +#endif /* S_ACCUM_H */ diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c index 21cbd3cf37..5fefae6c42 100644 --- a/src/mesa/swrast/s_atifragshader.c +++ b/src/mesa/swrast/s_atifragshader.c @@ -47,17 +47,12 @@ static void fetch_texel(GLcontext * ctx, const GLfloat texcoord[4], GLfloat lambda, GLuint unit, GLfloat color[4]) { - GLchan rgba[4]; SWcontext *swrast = SWRAST_CONTEXT(ctx); /* XXX use a float-valued TextureSample routine here!!! */ swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, 1, (const GLfloat(*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); + &lambda, (GLfloat (*)[4]) color); } static void @@ -591,8 +586,6 @@ _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span) /* incoming colors should be floats */ ASSERT(span->array->ChanType == GL_FLOAT); - ctx->_CurrentProgram = GL_FRAGMENT_SHADER_ATI; - for (i = 0; i < span->end; i++) { if (span->array->mask[i]) { init_machine(ctx, &machine, shader, span, i); @@ -608,6 +601,4 @@ _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span) } } } - - ctx->_CurrentProgram = 0; } diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c index 35b34e654f..b7a28a46e9 100644 --- a/src/mesa/swrast/s_bitmap.c +++ b/src/mesa/swrast/s_bitmap.c @@ -38,6 +38,8 @@ #include "s_span.h" +#if FEATURE_drawpix + /** * Render a bitmap. @@ -50,18 +52,17 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, const struct gl_pixelstore_attrib *unpack, const GLubyte *bitmap ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLint row, col; GLuint count = 0; SWspan span; ASSERT(ctx->RenderMode == GL_RENDER); - bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap); + bitmap = (const GLubyte *) _mesa_map_pbo_source(ctx, unpack, bitmap); if (!bitmap) return; - RENDER_START(swrast,ctx); + swrast_render_start(ctx); if (SWRAST_CONTEXT(ctx)->NewState) _swrast_validate_derived( ctx ); @@ -132,9 +133,9 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, } } - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); - _mesa_unmap_bitmap_pbo(ctx, unpack); + _mesa_unmap_pbo_source(ctx, unpack); } @@ -157,7 +158,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, ASSERT(ctx->RenderMode == GL_RENDER); ASSERT(bitmap); - RENDER_START(swrast,ctx); + swrast_render_start(ctx); if (SWRAST_CONTEXT(ctx)->NewState) _swrast_validate_derived( ctx ); @@ -224,6 +225,9 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, } } - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); } #endif + + +#endif /* FEATURE_drawpix */ diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c index bc4b2ac625..8303e4debc 100644 --- a/src/mesa/swrast/s_blit.c +++ b/src/mesa/swrast/s_blit.c @@ -24,6 +24,7 @@ #include "main/glheader.h" +#include "main/image.h" #include "main/macros.h" #include "s_context.h" @@ -104,7 +105,7 @@ static void blit_nearest(GLcontext *ctx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLenum buffer) + GLbitfield buffer) { struct gl_renderbuffer *readRb, *drawRb; @@ -456,7 +457,7 @@ static void simple_blit(GLcontext *ctx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLenum buffer) + GLbitfield buffer) { struct gl_renderbuffer *readRb, *drawRb; const GLint width = srcX1 - srcX0; @@ -551,184 +552,6 @@ simple_blit(GLcontext *ctx, /** - * Clip dst coords against Xmax (or Ymax). - */ -static INLINE void -clip_right_or_top(GLint *srcX0, GLint *srcX1, - GLint *dstX0, GLint *dstX1, - GLint maxValue) -{ - GLfloat t, bias; - - if (*dstX1 > maxValue) { - /* X1 outside right edge */ - ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */ - t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0); - /* chop off [t, 1] part */ - ASSERT(t >= 0.0 && t <= 1.0); - *dstX1 = maxValue; - bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; - *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias); - } - else if (*dstX0 > maxValue) { - /* X0 outside right edge */ - ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */ - t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1); - /* chop off [t, 1] part */ - ASSERT(t >= 0.0 && t <= 1.0); - *dstX0 = maxValue; - bias = (*srcX0 < *srcX1) ? -0.5 : 0.5; - *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias); - } -} - - -/** - * Clip dst coords against Xmin (or Ymin). - */ -static INLINE void -clip_left_or_bottom(GLint *srcX0, GLint *srcX1, - GLint *dstX0, GLint *dstX1, - GLint minValue) -{ - GLfloat t, bias; - - if (*dstX0 < minValue) { - /* X0 outside left edge */ - ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */ - t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0); - /* chop off [0, t] part */ - ASSERT(t >= 0.0 && t <= 1.0); - *dstX0 = minValue; - bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */ - *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias); - } - else if (*dstX1 < minValue) { - /* X1 outside left edge */ - ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */ - t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1); - /* chop off [0, t] part */ - ASSERT(t >= 0.0 && t <= 1.0); - *dstX1 = minValue; - bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; - *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias); - } -} - - -/** - * Do clipping of blit src/dest rectangles. - * The dest rect is clipped against both the buffer bounds and scissor bounds. - * The src rect is just clipped against the buffer bounds. - * - * When either the src or dest rect is clipped, the other is also clipped - * proportionately! - * - * Note that X0 need not be less than X1 (same for Y) for either the source - * and dest rects. That makes the clipping a little trickier. - * - * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped - */ -static GLboolean -clip_blit(GLcontext *ctx, - GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1, - GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1) -{ - const GLint srcXmin = 0; - const GLint srcXmax = ctx->ReadBuffer->Width; - const GLint srcYmin = 0; - const GLint srcYmax = ctx->ReadBuffer->Height; - - /* these include scissor bounds */ - const GLint dstXmin = ctx->DrawBuffer->_Xmin; - const GLint dstXmax = ctx->DrawBuffer->_Xmax; - const GLint dstYmin = ctx->DrawBuffer->_Ymin; - const GLint dstYmax = ctx->DrawBuffer->_Ymax; - - /* - printf("PreClipX: src: %d .. %d dst: %d .. %d\n", - *srcX0, *srcX1, *dstX0, *dstX1); - printf("PreClipY: src: %d .. %d dst: %d .. %d\n", - *srcY0, *srcY1, *dstY0, *dstY1); - */ - - /* trivial rejection tests */ - if (*dstX0 == *dstX1) - return GL_FALSE; /* no width */ - if (*dstX0 <= dstXmin && *dstX1 <= dstXmin) - return GL_FALSE; /* totally out (left) of bounds */ - if (*dstX0 >= dstXmax && *dstX1 >= dstXmax) - return GL_FALSE; /* totally out (right) of bounds */ - - if (*dstY0 == *dstY1) - return GL_FALSE; - if (*dstY0 <= dstYmin && *dstY1 <= dstYmin) - return GL_FALSE; - if (*dstY0 >= dstYmax && *dstY1 >= dstYmax) - return GL_FALSE; - - if (*srcX0 == *srcX1) - return GL_FALSE; - if (*srcX0 <= srcXmin && *srcX1 <= srcXmin) - return GL_FALSE; - if (*srcX0 >= srcXmax && *srcX1 >= srcXmax) - return GL_FALSE; - - if (*srcY0 == *srcY1) - return GL_FALSE; - if (*srcY0 <= srcYmin && *srcY1 <= srcYmin) - return GL_FALSE; - if (*srcY0 >= srcYmax && *srcY1 >= srcYmax) - return GL_FALSE; - - /* - * dest clip - */ - clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax); - clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax); - clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin); - clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin); - - /* - * src clip (just swap src/dst values from above) - */ - clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax); - clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax); - clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin); - clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin); - - /* - printf("PostClipX: src: %d .. %d dst: %d .. %d\n", - *srcX0, *srcX1, *dstX0, *dstX1); - printf("PostClipY: src: %d .. %d dst: %d .. %d\n", - *srcY0, *srcY1, *dstY0, *dstY1); - */ - - ASSERT(*dstX0 >= dstXmin); - ASSERT(*dstX0 <= dstXmax); - ASSERT(*dstX1 >= dstXmin); - ASSERT(*dstX1 <= dstXmax); - - ASSERT(*dstY0 >= dstYmin); - ASSERT(*dstY0 <= dstYmax); - ASSERT(*dstY1 >= dstYmin); - ASSERT(*dstY1 <= dstYmax); - - ASSERT(*srcX0 >= srcXmin); - ASSERT(*srcX0 <= srcXmax); - ASSERT(*srcX1 >= srcXmin); - ASSERT(*srcX1 <= srcXmax); - - ASSERT(*srcY0 >= srcYmin); - ASSERT(*srcY0 <= srcYmax); - ASSERT(*srcY1 >= srcYmin); - ASSERT(*srcY1 <= srcYmax); - - return GL_TRUE; -} - - -/** * Software fallback for glBlitFramebufferEXT(). */ void @@ -737,8 +560,7 @@ _swrast_BlitFramebuffer(GLcontext *ctx, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - static const GLint buffers[3] = { + static const GLbitfield buffers[3] = { GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT @@ -748,12 +570,12 @@ _swrast_BlitFramebuffer(GLcontext *ctx, if (!ctx->DrawBuffer->_NumColorDrawBuffers) return; - if (!clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1, - &dstX0, &dstY0, &dstX1, &dstY1)) { + if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1, + &dstX0, &dstY0, &dstX1, &dstY1)) { return; } - RENDER_START(swrast, ctx); + swrast_render_start(ctx); if (srcX1 - srcX0 == dstX1 - dstX0 && srcY1 - srcY0 == dstY1 - dstY0 && @@ -789,5 +611,5 @@ _swrast_BlitFramebuffer(GLcontext *ctx, } } - RENDER_FINISH(swrast, ctx); + swrast_render_finish(ctx); } diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_clear.c index 9e87d6d485..35080fd394 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_clear.c @@ -22,8 +22,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/** XXX This file should be named s_clear.c */ - #include "main/glheader.h" #include "main/colormac.h" #include "main/macros.h" @@ -307,8 +305,6 @@ clear_color_buffers(GLcontext *ctx) void _swrast_Clear(GLcontext *ctx, GLbitfield buffers) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); - #ifdef DEBUG_FOO { const GLbitfield legalBits = @@ -319,15 +315,12 @@ _swrast_Clear(GLcontext *ctx, GLbitfield buffers) BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL | BUFFER_BIT_ACCUM | - BUFFER_BIT_AUX0 | - BUFFER_BIT_AUX1 | - BUFFER_BIT_AUX2 | - BUFFER_BIT_AUX3; + BUFFER_BIT_AUX0; assert((buffers & (~legalBits)) == 0); } #endif - RENDER_START(swrast,ctx); + swrast_render_start(ctx); /* do software clearing here */ if (buffers) { @@ -347,5 +340,5 @@ _swrast_Clear(GLcontext *ctx, GLbitfield buffers) } } - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); } diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 62857ddeb0..abf0008565 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -61,7 +61,7 @@ _swrast_update_rasterflags( GLcontext *ctx ) if (ctx->Depth.Test) rasterMask |= DEPTH_BIT; if (swrast->_FogEnabled) rasterMask |= FOG_BIT; if (ctx->Scissor.Enabled) rasterMask |= CLIP_BIT; - if (ctx->Stencil.Enabled) rasterMask |= STENCIL_BIT; + if (ctx->Stencil._Enabled) rasterMask |= STENCIL_BIT; if (ctx->Visual.rgbMode) { const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask); if (colorMask != 0xffffffff) rasterMask |= MASKING_BIT; @@ -172,19 +172,29 @@ _swrast_update_fog_hint( GLcontext *ctx ) /** - * Update the swrast->_AnyTextureCombine flag. + * Update the swrast->_TextureCombinePrimary flag. */ static void _swrast_update_texture_env( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint i; - swrast->_AnyTextureCombine = GL_FALSE; + + swrast->_TextureCombinePrimary = 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; + const struct gl_tex_env_combine_state *combine = + ctx->Texture.Unit[i]._CurrentCombine; + GLuint term; + for (term = 0; term < combine->_NumArgsRGB; term++) { + if (combine->SourceRGB[term] == GL_PRIMARY_COLOR) { + swrast->_TextureCombinePrimary = GL_TRUE; + return; + } + if (combine->SourceA[term] == GL_PRIMARY_COLOR) { + swrast->_TextureCombinePrimary = GL_TRUE; + return; + } } } } @@ -206,10 +216,13 @@ _swrast_update_deferred_texture(GLcontext *ctx) else { const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; - if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR))) { + if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH))) { /* Z comes from fragment program/shader */ swrast->_DeferredTexture = GL_FALSE; } + else if (fprog && fprog->UsesKill) { + swrast->_DeferredTexture = GL_FALSE; + } else if (ctx->Query.CurrentOcclusionObject) { /* occlusion query depends on shader discard/kill results */ swrast->_DeferredTexture = GL_FALSE; @@ -254,19 +267,32 @@ _swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState) { const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; if (fp) { -#if 0 - /* XXX Need a way to trigger the initial loading of parameters - * even when there's no recent state changes. - */ - if (fp->Base.Parameters->StateFlags & newState) -#endif - _mesa_load_state_parameters(ctx, fp->Base.Parameters); + _mesa_load_state_parameters(ctx, fp->Base.Parameters); } } +/** + * See if we can do early diffuse+specular (primary+secondary) color + * add per vertex instead of per-fragment. + */ +static void +_swrast_update_specular_vertex_add(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLboolean separateSpecular = ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR); + + swrast->SpecularVertexAdd = (separateSpecular + && ctx->Texture._EnabledUnits == 0x0 + && !ctx->FragmentProgram._Current + && !ctx->ATIFragmentShader._Enabled); +} + #define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \ + _NEW_PROGRAM_CONSTANTS | \ _NEW_TEXTURE | \ _NEW_HINT | \ _NEW_POLYGON ) @@ -326,9 +352,7 @@ _swrast_validate_triangle( GLcontext *ctx, swrast->choose_triangle( ctx ); ASSERT(swrast->Triangle); - if (ctx->Texture._EnabledUnits == 0 - && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Current) { + if (swrast->SpecularVertexAdd) { /* separate specular color, but no texture */ swrast->SpecTriangle = swrast->Triangle; swrast->Triangle = _swrast_add_spec_terms_triangle; @@ -350,9 +374,7 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) swrast->choose_line( ctx ); ASSERT(swrast->Line); - if (ctx->Texture._EnabledUnits == 0 - && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Current) { + if (swrast->SpecularVertexAdd) { swrast->SpecLine = swrast->Line; swrast->Line = _swrast_add_spec_terms_line; } @@ -372,9 +394,7 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) _swrast_validate_derived( ctx ); swrast->choose_point( ctx ); - if (ctx->Texture._EnabledUnits == 0 - && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Current) { + if (swrast->SpecularVertexAdd) { swrast->SpecPoint = swrast->Point; swrast->Point = _swrast_add_spec_terms_point; } @@ -502,13 +522,6 @@ _swrast_invalidate_state( GLcontext *ctx, GLbitfield new_state ) new_state = ~0; } - { - const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; - if (fp && (fp->Base.Parameters->StateFlags & new_state)) { - _mesa_load_state_parameters(ctx, fp->Base.Parameters); - } - } - if (new_state & swrast->InvalidateTriangleMask) swrast->Triangle = _swrast_validate_triangle; @@ -533,6 +546,9 @@ _swrast_update_texture_samplers(GLcontext *ctx) SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint u; + if (!swrast) + return; /* pipe hack */ + for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { const struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current; /* Note: If tObj is NULL, the sample function will be a simple @@ -622,17 +638,7 @@ _swrast_validate_derived( GLcontext *ctx ) if (swrast->NewState & (_NEW_FOG | _NEW_PROGRAM)) _swrast_update_fog_state( ctx ); - if (swrast->NewState & (_NEW_MODELVIEW | - _NEW_PROJECTION | - _NEW_TEXTURE_MATRIX | - _NEW_FOG | - _NEW_LIGHT | - _NEW_LINE | - _NEW_TEXTURE | - _NEW_TRANSFORM | - _NEW_POINT | - _NEW_VIEWPORT | - _NEW_PROGRAM)) + if (swrast->NewState & (_NEW_PROGRAM_CONSTANTS | _NEW_PROGRAM)) _swrast_update_fragment_program( ctx, swrast->NewState ); if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) { @@ -653,6 +659,12 @@ _swrast_validate_derived( GLcontext *ctx ) _NEW_TEXTURE)) _swrast_update_active_attribs(ctx); + if (swrast->NewState & (_NEW_FOG | + _NEW_PROGRAM | + _NEW_LIGHT | + _NEW_TEXTURE)) + _swrast_update_specular_vertex_add(ctx); + swrast->NewState = 0; swrast->StateChanges = 0; swrast->InvalidateState = _swrast_invalidate_state; @@ -817,8 +829,8 @@ _swrast_CreateContext( GLcontext *ctx ) swrast->PointSpan.facing = 0; swrast->PointSpan.array = swrast->SpanArrays; - swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureImageUnits * - MAX_WIDTH * 4 * sizeof(GLchan)); + swrast->TexelBuffer = (GLfloat *) MALLOC(ctx->Const.MaxTextureImageUnits * + MAX_WIDTH * 4 * sizeof(GLfloat)); if (!swrast->TexelBuffer) { FREE(swrast->SpanArrays); FREE(swrast); diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index a511d1c9a1..9059f9b5ec 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -52,7 +52,7 @@ typedef void (*texture_sample_func)(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]); + const GLfloat lambda[], GLfloat rgba[][4]); typedef void (_ASMAPIP blend_func)( GLcontext *ctx, GLuint n, const GLubyte mask[], @@ -131,7 +131,7 @@ typedef struct GLfloat _BackfaceSign; /** +1 or -1 */ GLfloat _BackfaceCullSign; /** +1, 0, or -1 */ GLboolean _PreferPixelFog; /* Compute fog blend factor per fragment? */ - GLboolean _AnyTextureCombine; + GLboolean _TextureCombinePrimary; GLboolean _FogEnabled; GLboolean _DeferredTexture; GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */ @@ -157,6 +157,7 @@ typedef struct GLbitfield NewState; GLuint StateChanges; GLenum Primitive; /* current primitive being drawn (ala glBegin) */ + GLboolean SpecularVertexAdd; /**< Add specular/secondary color per vertex */ void (*InvalidateState)( GLcontext *ctx, GLbitfield new_state ); @@ -221,7 +222,7 @@ typedef struct /** Buffer for saving the sampled texture colors. * Needed for GL_ARB_texture_env_crossbar implementation. */ - GLchan *TexelBuffer; + GLfloat *TexelBuffer; validate_texture_image_func ValidateTextureImage; @@ -238,21 +239,43 @@ extern void _swrast_update_texture_samplers(GLcontext *ctx); -#define SWRAST_CONTEXT(ctx) ((SWcontext *)ctx->swrast_context) +/** Return SWcontext for the given GLcontext */ +static INLINE SWcontext * +SWRAST_CONTEXT(GLcontext *ctx) +{ + return (SWcontext *) ctx->swrast_context; +} + +/** const version of above */ +static INLINE const SWcontext * +CONST_SWRAST_CONTEXT(const GLcontext *ctx) +{ + return (const SWcontext *) ctx->swrast_context; +} + + +/** + * Called prior to framebuffer reading/writing. + * For drivers that rely on swrast for fallback rendering, this is the + * driver's opportunity to map renderbuffers and textures. + */ +static INLINE void +swrast_render_start(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + if (swrast->Driver.SpanRenderStart) + swrast->Driver.SpanRenderStart(ctx); +} -#define RENDER_START(SWctx, GLctx) \ - do { \ - if ((SWctx)->Driver.SpanRenderStart) { \ - (*(SWctx)->Driver.SpanRenderStart)(GLctx); \ - } \ - } while (0) -#define RENDER_FINISH(SWctx, GLctx) \ - do { \ - if ((SWctx)->Driver.SpanRenderFinish) { \ - (*(SWctx)->Driver.SpanRenderFinish)(GLctx); \ - } \ - } while (0) +/** Called after framebuffer reading/writing */ +static INLINE void +swrast_render_finish(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + if (swrast->Driver.SpanRenderFinish) + swrast->Driver.SpanRenderFinish(ctx); +} @@ -267,6 +290,34 @@ _swrast_update_texture_samplers(GLcontext *ctx); /* + * Fixed point arithmetic macros + */ +#ifndef FIXED_FRAC_BITS +#define FIXED_FRAC_BITS 11 +#endif + +#define FIXED_SHIFT FIXED_FRAC_BITS +#define FIXED_ONE (1 << FIXED_SHIFT) +#define FIXED_HALF (1 << (FIXED_SHIFT-1)) +#define FIXED_FRAC_MASK (FIXED_ONE - 1) +#define FIXED_INT_MASK (~FIXED_FRAC_MASK) +#define FIXED_EPSILON 1 +#define FIXED_SCALE ((float) FIXED_ONE) +#define FIXED_DBL_SCALE ((double) FIXED_ONE) +#define FloatToFixed(X) (IROUND((X) * FIXED_SCALE)) +#define FixedToDouble(X) ((X) * (1.0 / FIXED_DBL_SCALE)) +#define IntToFixed(I) ((I) << FIXED_SHIFT) +#define FixedToInt(X) ((X) >> FIXED_SHIFT) +#define FixedToUns(X) (((unsigned int)(X)) >> FIXED_SHIFT) +#define FixedCeil(X) (((X) + FIXED_ONE - FIXED_EPSILON) & FIXED_INT_MASK) +#define FixedFloor(X) ((X) & FIXED_INT_MASK) +#define FixedToFloat(X) ((X) * (1.0F / FIXED_SCALE)) +#define PosFloatToFixed(X) FloatToFixed(X) +#define SignedFloatToFixed(X) FloatToFixed(X) + + + +/* * XXX these macros are just bandages for now in order to make * CHAN_BITS==32 compile cleanly. * These should probably go elsewhere at some point. diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index fc5990b261..8f2db3afbb 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -40,6 +40,8 @@ #include "s_zoom.h" +#if FEATURE_drawpix + /** * Determine if there's overlap in an image copy. @@ -899,7 +901,7 @@ _swrast_CopyPixels( GLcontext *ctx, GLint destx, GLint desty, GLenum type ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - RENDER_START(swrast,ctx); + swrast_render_start(ctx); if (swrast->NewState) _swrast_validate_derived( ctx ); @@ -928,5 +930,8 @@ _swrast_CopyPixels( GLcontext *ctx, } } - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); } + + +#endif /* FEATURE_drawpix */ diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c index 26e23f02d5..1a428fb1a2 100644 --- a/src/mesa/swrast/s_depth.c +++ b/src/mesa/swrast/s_depth.c @@ -497,6 +497,33 @@ depth_test_span32( GLcontext *ctx, GLuint n, return passed; } +/* Apply ARB_depth_clamp to span of fragments. */ +void +_swrast_depth_clamp_span( GLcontext *ctx, SWspan *span ) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + struct gl_renderbuffer *rb = fb->_DepthBuffer; + const GLuint count = span->end; + GLuint *zValues = span->array->z; + GLuint near, far; + int i; + + if (rb->DataType == GL_UNSIGNED_SHORT) { + near = FLOAT_TO_UINT(ctx->Viewport.Near); + far = FLOAT_TO_UINT(ctx->Viewport.Far); + } else { + assert(rb->DataType == GL_UNSIGNED_INT); + CLAMPED_FLOAT_TO_USHORT(near, ctx->Viewport.Near); + CLAMPED_FLOAT_TO_USHORT(far, ctx->Viewport.Far); + } + for (i = 0; i < count; i++) { + if (zValues[i] < near) + zValues[i] = near; + if (zValues[i] > far) + zValues[i] = far; + } +} + /* diff --git a/src/mesa/swrast/s_depth.h b/src/mesa/swrast/s_depth.h index 3688625683..7eae366742 100644 --- a/src/mesa/swrast/s_depth.h +++ b/src/mesa/swrast/s_depth.h @@ -33,6 +33,8 @@ extern GLuint _swrast_depth_test_span( GLcontext *ctx, SWspan *span); +extern void +_swrast_depth_clamp_span( GLcontext *ctx, SWspan *span ); extern GLboolean _swrast_depth_bounds_test( GLcontext *ctx, SWspan *span ); diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index 7af3e3dad1..6ce449b2a8 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -39,6 +39,8 @@ #include "s_zoom.h" +#if FEATURE_drawpix + /** * Try to do a fast and simple RGB(a) glDrawPixels. @@ -829,8 +831,19 @@ _swrast_DrawPixels( GLcontext *ctx, const GLvoid *pixels ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLboolean save_vp_override = ctx->VertexProgram._Overriden; + + /* We are creating fragments directly, without going through vertex + * programs. + * + * This override flag tells the fragment processing code that its input + * comes from a non-standard source, and it may therefore not rely on + * optimizations that assume e.g. constant color if there is no color + * vertex array. + */ + _mesa_set_vp_override(ctx, GL_TRUE); - RENDER_START(swrast,ctx); + swrast_render_start(ctx); if (ctx->NewState) _mesa_update_state(ctx); @@ -838,9 +851,10 @@ _swrast_DrawPixels( GLcontext *ctx, if (swrast->NewState) _swrast_validate_derived( ctx ); - pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels); + pixels = _mesa_map_pbo_source(ctx, unpack, pixels); if (!pixels) { - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); + _mesa_set_vp_override(ctx, save_vp_override); return; } @@ -879,60 +893,11 @@ _swrast_DrawPixels( GLcontext *ctx, /* don't return yet, clean-up */ } - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); + _mesa_set_vp_override(ctx, save_vp_override); - _mesa_unmap_drapix_pbo(ctx, unpack); + _mesa_unmap_pbo_source(ctx, unpack); } - -#if 0 /* experimental */ -/* - * Execute glDrawDepthPixelsMESA(). - */ -void -_swrast_DrawDepthPixelsMESA( GLcontext *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum colorFormat, GLenum colorType, - const GLvoid *colors, - GLenum depthType, const GLvoid *depths, - const struct gl_pixelstore_attrib *unpack ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - if (swrast->NewState) - _swrast_validate_derived( ctx ); - - RENDER_START(swrast,ctx); - - switch (colorFormat) { - case GL_COLOR_INDEX: - if (ctx->Visual.rgbMode) - draw_rgba_pixels(ctx, x,y, width, height, colorFormat, colorType, - unpack, colors); - else - draw_index_pixels(ctx, x, y, width, height, colorType, - unpack, colors); - break; - case GL_RED: - case GL_GREEN: - case GL_BLUE: - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_RGB: - case GL_BGR: - case GL_RGBA: - case GL_BGRA: - case GL_ABGR_EXT: - draw_rgba_pixels(ctx, x, y, width, height, colorFormat, colorType, - unpack, colors); - break; - default: - _mesa_problem(ctx, "unexpected format in glDrawDepthPixelsMESA"); - } - - RENDER_FINISH(swrast,ctx); -} -#endif +#endif /* FEATURE_drawpix */ diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c index aa79531277..0eea1d0c3b 100644 --- a/src/mesa/swrast/s_feedback.c +++ b/src/mesa/swrast/s_feedback.c @@ -34,6 +34,8 @@ #include "s_triangle.h" +#if FEATURE_feedback + static void feedback_vertex(GLcontext * ctx, const SWvertex * v, const SWvertex * pv) @@ -58,9 +60,9 @@ void _swrast_feedback_triangle(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1, const SWvertex *v2) { - if (_swrast_culltriangle(ctx, v0, v1, v2)) { - FEEDBACK_TOKEN(ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN); - FEEDBACK_TOKEN(ctx, (GLfloat) 3); /* three vertices */ + if (!_swrast_culltriangle(ctx, v0, v1, v2)) { + _mesa_feedback_token(ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN); + _mesa_feedback_token(ctx, (GLfloat) 3); /* three vertices */ if (ctx->Light.ShadeModel == GL_SMOOTH) { feedback_vertex(ctx, v0, v0); @@ -86,7 +88,7 @@ _swrast_feedback_line(GLcontext *ctx, const SWvertex *v0, if (swrast->StippleCounter == 0) token = GL_LINE_RESET_TOKEN; - FEEDBACK_TOKEN(ctx, (GLfloat) (GLint) token); + _mesa_feedback_token(ctx, (GLfloat) (GLint) token); if (ctx->Light.ShadeModel == GL_SMOOTH) { feedback_vertex(ctx, v0, v0); @@ -104,7 +106,7 @@ _swrast_feedback_line(GLcontext *ctx, const SWvertex *v0, void _swrast_feedback_point(GLcontext *ctx, const SWvertex *v) { - FEEDBACK_TOKEN(ctx, (GLfloat) (GLint) GL_POINT_TOKEN); + _mesa_feedback_token(ctx, (GLfloat) (GLint) GL_POINT_TOKEN); feedback_vertex(ctx, v, v); } @@ -113,7 +115,7 @@ void _swrast_select_triangle(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1, const SWvertex *v2) { - if (_swrast_culltriangle(ctx, v0, v1, v2)) { + if (!_swrast_culltriangle(ctx, v0, v1, v2)) { const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs ); @@ -138,3 +140,6 @@ _swrast_select_point(GLcontext *ctx, const SWvertex *v) const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; _mesa_update_hitflag( ctx, v->attrib[FRAG_ATTRIB_WPOS][2] * zs ); } + + +#endif /* FEATURE_feedback */ diff --git a/src/mesa/swrast/s_feedback.h b/src/mesa/swrast/s_feedback.h index 9feab75dbb..994984f6f7 100644 --- a/src/mesa/swrast/s_feedback.h +++ b/src/mesa/swrast/s_feedback.h @@ -31,6 +31,8 @@ #include "swrast.h" +#if FEATURE_feedback + extern void _swrast_feedback_point( GLcontext *ctx, const SWvertex *v ); extern void _swrast_feedback_line( GLcontext *ctx, @@ -46,5 +48,48 @@ extern void _swrast_select_line( GLcontext *ctx, extern void _swrast_select_triangle( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1, const SWvertex *v2 ); +#else /* FEATURE_feedback */ + +static INLINE void +_swrast_feedback_point( GLcontext *ctx, const SWvertex *v ) +{ + ASSERT_NO_FEATURE(); +} + +static INLINE void +_swrast_feedback_line( GLcontext *ctx, + const SWvertex *v1, const SWvertex *v2 ) +{ + ASSERT_NO_FEATURE(); +} + +static INLINE void +_swrast_feedback_triangle( GLcontext *ctx, const SWvertex *v0, + const SWvertex *v1, const SWvertex *v2 ) +{ + ASSERT_NO_FEATURE(); +} + +static INLINE void +_swrast_select_point( GLcontext *ctx, const SWvertex *v ) +{ + ASSERT_NO_FEATURE(); +} + +static INLINE void +_swrast_select_line( GLcontext *ctx, + const SWvertex *v1, const SWvertex *v2 ) +{ + ASSERT_NO_FEATURE(); +} + +static INLINE void +_swrast_select_triangle( GLcontext *ctx, const SWvertex *v0, + const SWvertex *v1, const SWvertex *v2 ) +{ + ASSERT_NO_FEATURE(); +} #endif + +#endif /* S_FEEDBACK_H */ diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index b9ba265db6..77ed0cfef9 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -164,7 +164,7 @@ else { \ void _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) { - const SWcontext *swrast = SWRAST_CONTEXT(ctx); + const SWcontext *swrast = CONST_SWRAST_CONTEXT(ctx); GLfloat rFog, gFog, bFog; ASSERT(swrast->_FogEnabled); @@ -283,7 +283,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) void _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) { - const SWcontext *swrast = SWRAST_CONTEXT(ctx); + const SWcontext *swrast = CONST_SWRAST_CONTEXT(ctx); const GLuint fogIndex = (GLuint) ctx->Fog.Index; GLuint *index = span->array->index; diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 525cf9d724..613a91b0ec 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -33,6 +33,32 @@ /** + * Apply texture object's swizzle (X/Y/Z/W/0/1) to incoming 'texel' + * and return results in 'colorOut'. + */ +static INLINE void +swizzle_texel(const GLfloat texel[4], GLfloat colorOut[4], GLuint swizzle) +{ + if (swizzle == SWIZZLE_NOOP) { + COPY_4V(colorOut, texel); + } + else { + GLfloat vector[6]; + vector[SWIZZLE_X] = texel[0]; + vector[SWIZZLE_Y] = texel[1]; + vector[SWIZZLE_Z] = texel[2]; + vector[SWIZZLE_W] = texel[3]; + vector[SWIZZLE_ZERO] = 0.0F; + vector[SWIZZLE_ONE] = 1.0F; + colorOut[0] = vector[GET_SWZ(swizzle, 0)]; + colorOut[1] = vector[GET_SWZ(swizzle, 1)]; + colorOut[2] = vector[GET_SWZ(swizzle, 2)]; + colorOut[3] = vector[GET_SWZ(swizzle, 3)]; + } +} + + +/** * Fetch a texel with given lod. * Called via machine->FetchTexelLod() */ @@ -40,20 +66,22 @@ static void fetch_texel_lod( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, GLuint unit, GLfloat color[4] ) { - GLchan rgba[4]; - SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - if (texObj) + if (texObj) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLfloat rgba[4]; + lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod); - /* XXX use a float-valued TextureSample routine here!!! */ - swrast->TextureSample[unit](ctx, texObj, 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); + swrast->TextureSample[unit](ctx, texObj, 1, + (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + swizzle_texel(rgba, color, texObj->_Swizzle); + } + else { + ASSIGN_4V(color, 0.0F, 0.0F, 0.0F, 1.0F); + } } @@ -69,13 +97,14 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], { SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - GLfloat lambda; - GLchan rgba[4]; if (texObj) { - const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; + const struct gl_texture_image *texImg = + texObj->Image[0][texObj->BaseLevel]; const GLfloat texW = (GLfloat) texImg->WidthScale; const GLfloat texH = (GLfloat) texImg->HeightScale; + GLfloat lambda; + GLfloat rgba[4]; lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ texdx[1], texdy[1], /* dt/dx, dt/dy */ @@ -85,14 +114,15 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], 1.0F / texcoord[3]) + lodBias; lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod); - } - swrast->TextureSample[unit](ctx, texObj, 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); + swrast->TextureSample[unit](ctx, texObj, 1, + (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + swizzle_texel(rgba, color, texObj->_Swizzle); + } + else { + ASSIGN_4V(color, 0.0F, 0.0F, 0.0F, 1.0F); + } } @@ -127,9 +157,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine, /* if running a GLSL program (not ARB_fragment_program) */ if (ctx->Shader.CurrentProgram) { - /* Store front/back facing value in register FOGC.Y */ - machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = 1.0 - span->facing; - /* Note FOGC.ZW is gl_PointCoord if drawing a sprite */ + /* Store front/back facing value */ + machine->Attribs[FRAG_ATTRIB_FACE][col][0] = 1.0 - span->facing; } machine->CurElement = col; @@ -167,9 +196,9 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) if (_mesa_execute_program(ctx, &program->Base, machine)) { /* Store result color */ - if (outputsWritten & (1 << FRAG_RESULT_COLR)) { + if (outputsWritten & (1 << FRAG_RESULT_COLOR)) { COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], - machine->Outputs[FRAG_RESULT_COLR]); + machine->Outputs[FRAG_RESULT_COLOR]); } else { /* Multiple drawbuffers / render targets @@ -186,8 +215,8 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) } /* Store result depth/z */ - if (outputsWritten & (1 << FRAG_RESULT_DEPR)) { - const GLfloat depth = machine->Outputs[FRAG_RESULT_DEPR][2]; + if (outputsWritten & (1 << FRAG_RESULT_DEPTH)) { + const GLfloat depth = machine->Outputs[FRAG_RESULT_DEPTH][2]; if (depth <= 0.0) span->array->z[i] = 0; else if (depth >= 1.0) @@ -220,20 +249,16 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) ASSERT(span->array->ChanType == GL_FLOAT); } - ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ - run_program(ctx, span, 0, span->end); - if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR)) { + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLOR)) { span->interpMask &= ~SPAN_RGBA; span->arrayMask |= SPAN_RGBA; } - if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH)) { span->interpMask &= ~SPAN_Z; span->arrayMask |= SPAN_Z; } - - ctx->_CurrentProgram = 0; } diff --git a/src/mesa/swrast/s_imaging.c b/src/mesa/swrast/s_imaging.c index 591857c342..7cc97b7f03 100644 --- a/src/mesa/swrast/s_imaging.c +++ b/src/mesa/swrast/s_imaging.c @@ -34,12 +34,14 @@ #include "s_span.h" +#if FEATURE_colortable + + void _swrast_CopyColorTable( GLcontext *ctx, GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLchan data[MAX_WIDTH][4]; struct gl_buffer_object *bufferSave; @@ -51,17 +53,17 @@ _swrast_CopyColorTable( GLcontext *ctx, if (width > MAX_WIDTH) width = MAX_WIDTH; - RENDER_START( swrast, ctx ); + swrast_render_start(ctx); /* read the data from framebuffer */ _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, width, x, y, CHAN_TYPE, data ); - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data); @@ -74,7 +76,6 @@ void _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLchan data[MAX_WIDTH][4]; struct gl_buffer_object *bufferSave; @@ -86,17 +87,17 @@ _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, if (width > MAX_WIDTH) width = MAX_WIDTH; - RENDER_START( swrast, ctx ); + swrast_render_start(ctx); /* read the data from framebuffer */ _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, width, x, y, CHAN_TYPE, data ); - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data); @@ -105,12 +106,17 @@ _swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, } +#endif /* FEATURE_colortable */ + + +#if FEATURE_convolve + + void _swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLchan rgba[MAX_CONVOLUTION_WIDTH][4]; struct gl_buffer_object *bufferSave; @@ -119,17 +125,17 @@ _swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, return; } - RENDER_START( swrast, ctx ); + swrast_render_start(ctx); /* read the data from framebuffer */ _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, width, x, y, CHAN_TYPE, rgba ); - RENDER_FINISH( swrast, ctx ); + swrast_render_finish(ctx); /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; /* store as convolution filter */ _mesa_ConvolutionFilter1D(target, internalFormat, width, @@ -145,7 +151,6 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); struct gl_pixelstore_attrib packSave; GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4]; GLint i; @@ -156,7 +161,7 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, return; } - RENDER_START(swrast,ctx); + swrast_render_start(ctx); /* read pixels from framebuffer */ for (i = 0; i < height; i++) { @@ -164,7 +169,7 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, width, x, y + i, CHAN_TYPE, rgba[i] ); } - RENDER_FINISH(swrast,ctx); + swrast_render_finish(ctx); /* * HACK: save & restore context state so we can store this as a @@ -182,12 +187,12 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, ctx->Unpack.SkipImages = 0; ctx->Unpack.SwapBytes = GL_FALSE; ctx->Unpack.LsbFirst = GL_FALSE; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; ctx->NewState |= _NEW_PACKUNPACK; /* save PBO binding */ bufferSave = ctx->Unpack.BufferObj; - ctx->Unpack.BufferObj = ctx->Array.NullBufferObj; + ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj; _mesa_ConvolutionFilter2D(target, internalFormat, width, height, GL_RGBA, CHAN_TYPE, rgba); @@ -198,3 +203,6 @@ _swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, ctx->Unpack = packSave; /* restore pixel packing params */ ctx->NewState |= _NEW_PACKUNPACK; } + + +#endif /* FEATURE_convolve */ diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 61ff4d0b84..50ec2063a5 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -139,9 +139,10 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) } ATTRIB_LOOP_BEGIN - if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) { + if (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) { + /* a texcoord attribute */ const GLuint u = attr - FRAG_ATTRIB_TEX0; - /* a texcoord */ + ASSERT(u < Elements(ctx->Point.CoordReplace)); if (ctx->Point.CoordReplace[u]) { tCoords[numTcoords++] = attr; @@ -170,15 +171,15 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) continue; } } - else if (attr == FRAG_ATTRIB_FOGC) { - /* GLSL gl_PointCoord is stored in fog.zw */ - span.attrStart[FRAG_ATTRIB_FOGC][2] = 0.0; - span.attrStart[FRAG_ATTRIB_FOGC][3] = 0.0; /* t0 set below */ - span.attrStepX[FRAG_ATTRIB_FOGC][2] = dsdx; - span.attrStepX[FRAG_ATTRIB_FOGC][3] = 0.0; - span.attrStepY[FRAG_ATTRIB_FOGC][2] = 0.0; - span.attrStepY[FRAG_ATTRIB_FOGC][3] = dtdy; - tCoords[numTcoords++] = FRAG_ATTRIB_FOGC; + else if (attr == FRAG_ATTRIB_PNTC) { + /* GLSL gl_PointCoord.xy (.zw undefined) */ + span.attrStart[FRAG_ATTRIB_PNTC][0] = 0.0; + span.attrStart[FRAG_ATTRIB_PNTC][1] = 0.0; /* t0 set below */ + span.attrStepX[FRAG_ATTRIB_PNTC][0] = dsdx; + span.attrStepX[FRAG_ATTRIB_PNTC][1] = 0.0; + span.attrStepY[FRAG_ATTRIB_PNTC][0] = 0.0; + span.attrStepY[FRAG_ATTRIB_PNTC][1] = dtdy; + tCoords[numTcoords++] = FRAG_ATTRIB_PNTC; continue; } /* use vertex's texcoord/attrib */ @@ -221,10 +222,7 @@ sprite_point(GLcontext *ctx, const SWvertex *vert) GLuint i; /* setup texcoord T for this row */ for (i = 0; i < numTcoords; i++) { - if (tCoords[i] == FRAG_ATTRIB_FOGC) - span.attrStart[FRAG_ATTRIB_FOGC][3] = tcoord; - else - span.attrStart[tCoords[i]][1] = tcoord; + span.attrStart[tCoords[i]][1] = tcoord; } /* these might get changed by span clipping */ @@ -570,6 +568,9 @@ void _swrast_choose_point(GLcontext *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLfloat size = CLAMP(ctx->Point.Size, + ctx->Point.MinSize, + ctx->Point.MaxSize); if (ctx->RenderMode == GL_RENDER) { if (ctx->Point.PointSprite) { @@ -578,7 +579,7 @@ _swrast_choose_point(GLcontext *ctx) else if (ctx->Point.SmoothFlag) { swrast->Point = smooth_point; } - else if (ctx->Point.Size > 1.0 || + else if (size > 1.0 || ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) { swrast->Point = large_point; diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index f263045170..48b9408d24 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -555,11 +555,11 @@ _swrast_ReadPixels( GLcontext *ctx, SWcontext *swrast = SWRAST_CONTEXT(ctx); struct gl_pixelstore_attrib clippedPacking = *packing; - /* Need to do RENDER_START before clipping or anything else since this - * is where a driver may grab the hw lock and get an updated window - * size. + /* Need to do swrast_render_start() before clipping or anything else + * since this is where a driver may grab the hw lock and get an updated + * window size. */ - RENDER_START(swrast, ctx); + swrast_render_start(ctx); if (ctx->NewState) _mesa_update_state(ctx); @@ -570,11 +570,11 @@ _swrast_ReadPixels( GLcontext *ctx, /* Do all needed clipping here, so that we can forget about it later */ if (!_mesa_clip_readpixels(ctx, &x, &y, &width, &height, &clippedPacking)) { /* The ReadPixels region is totally outside the window bounds */ - RENDER_FINISH(swrast, ctx); + swrast_render_finish(ctx); return; } - pixels = _mesa_map_readpix_pbo(ctx, &clippedPacking, pixels); + pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels); if (!pixels) return; @@ -614,7 +614,7 @@ _swrast_ReadPixels( GLcontext *ctx, /* don't return yet, clean-up */ } - RENDER_FINISH(swrast, ctx); + swrast_render_finish(ctx); - _mesa_unmap_readpix_pbo(ctx, &clippedPacking); + _mesa_unmap_pbo_dest(ctx, &clippedPacking); } diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 7f9cc64bb2..704230d1d7 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 7.1 + * Version: 7.5 * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. 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"), @@ -188,10 +189,10 @@ interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) const GLfloat dv1dx = span->attrStepX[attr][1]; const GLfloat dv2dx = span->attrStepX[attr][2]; const GLfloat dv3dx = span->attrStepX[attr][3]; - GLfloat v0 = span->attrStart[attr][0]; - GLfloat v1 = span->attrStart[attr][1]; - GLfloat v2 = span->attrStart[attr][2]; - GLfloat v3 = span->attrStart[attr][3]; + GLfloat v0 = span->attrStart[attr][0] + span->leftClip * dv0dx; + GLfloat v1 = span->attrStart[attr][1] + span->leftClip * dv1dx; + GLfloat v2 = span->attrStart[attr][2] + span->leftClip * dv2dx; + GLfloat v3 = span->attrStart[attr][3] + span->leftClip * dv3dx; GLuint k; for (k = 0; k < span->end; k++) { const GLfloat invW = 1.0f / w; @@ -442,11 +443,10 @@ _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ) * Compute mipmap LOD from partial derivatives. * This the ideal solution, as given in the OpenGL spec. */ -#if 0 -static GLfloat -compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, - GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, - GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) +GLfloat +_swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, + GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, + GLfloat s, GLfloat t, GLfloat q, GLfloat invQ) { GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ); GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ); @@ -458,13 +458,13 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, GLfloat lambda = LOG2(rho); return lambda; } -#endif /** * Compute mipmap LOD from partial derivatives. * This is a faster approximation than above function. */ +#if 0 GLfloat _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, @@ -485,6 +485,7 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, lambda = LOG2(rho); return lambda; } +#endif /** @@ -521,10 +522,10 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) const GLfloat drdx = span->attrStepX[attr][2]; const GLfloat dqdx = span->attrStepX[attr][3]; const GLfloat dqdy = span->attrStepY[attr][3]; - GLfloat s = span->attrStart[attr][0]; - GLfloat t = span->attrStart[attr][1]; - GLfloat r = span->attrStart[attr][2]; - GLfloat q = span->attrStart[attr][3]; + GLfloat s = span->attrStart[attr][0] + span->leftClip * dsdx; + GLfloat t = span->attrStart[attr][1] + span->leftClip * dtdx; + GLfloat r = span->attrStart[attr][2] + span->leftClip * drdx; + GLfloat q = span->attrStart[attr][3] + span->leftClip * dqdx; if (obj) { const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; @@ -546,7 +547,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dwdx; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -587,7 +588,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dwdx; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -660,8 +661,8 @@ interpolate_wpos(GLcontext *ctx, SWspan *span) } } - w = span->attrStart[FRAG_ATTRIB_WPOS][3]; dw = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + w = span->attrStart[FRAG_ATTRIB_WPOS][3] + span->leftClip * dw; for (i = 0; i < span->end; i++) { wpos[i][2] = (GLfloat) span->array->z[i] * zScale; wpos[i][3] = w; @@ -726,6 +727,8 @@ clip_span( GLcontext *ctx, SWspan *span ) const GLint ymin = ctx->DrawBuffer->_Ymin; const GLint ymax = ctx->DrawBuffer->_Ymax; + span->leftClip = 0; + if (span->arrayMask & SPAN_XY) { /* arrays of x/y pixel coords */ const GLint *x = span->array->x; @@ -753,7 +756,7 @@ clip_span( GLcontext *ctx, SWspan *span ) /* horizontal span of pixels */ const GLint x = span->x; const GLint y = span->y; - const GLint n = span->end; + GLint n = span->end; /* Trivial rejection tests */ if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) { @@ -761,18 +764,44 @@ clip_span( GLcontext *ctx, SWspan *span ) return GL_FALSE; /* all pixels clipped */ } + /* Clip to right */ + if (x + n > xmax) { + ASSERT(x < xmax); + n = span->end = xmax - x; + } + /* Clip to the left */ if (x < xmin) { + const GLint leftClip = xmin - x; + GLuint i; + + ASSERT(leftClip > 0); ASSERT(x + n > xmin); + + /* Clip 'leftClip' pixels from the left side. + * The span->leftClip field will be applied when we interpolate + * fragment attributes. + * For arrays of values, shift them left. + */ + for (i = 0; i < FRAG_ATTRIB_MAX; i++) { + if (span->arrayAttribs & (1 << i)) { + /* shift array elements left by 'leftClip' */ + _mesa_memcpy(span->array->attribs[i], + span->array->attribs[i] + leftClip, + (n - leftClip) * 4 * sizeof(GLfloat)); + } + } + + span->leftClip = leftClip; + span->x = xmin; + span->end -= leftClip; span->writeAll = GL_FALSE; - _mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte)); } - /* Clip to right */ - if (x + n > xmax) { - ASSERT(x < xmax); - span->end = xmax - x; - } + ASSERT(span->x >= xmin); + ASSERT(span->x + span->end <= xmax); + ASSERT(span->y >= ymin); + ASSERT(span->y < ymax); return GL_TRUE; /* some pixels visible */ } @@ -818,6 +847,12 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) } } + if (!(span->arrayMask & SPAN_MASK)) { + /* post-clip sanity check */ + assert(span->x >= 0); + assert(span->y >= 0); + } + /* Depth bounds test */ if (ctx->Depth.BoundsTest && fb->Visual.depthBits > 0) { if (!_swrast_depth_bounds_test(ctx, span)) { @@ -845,12 +880,15 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) stipple_polygon_span(ctx, span); } + if (ctx->Transform.DepthClamp) + _swrast_depth_clamp_span(ctx, span); + /* Stencil and Z testing */ - if (ctx->Depth.Test || ctx->Stencil.Enabled) { + if (ctx->Stencil._Enabled || ctx->Depth.Test) { if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z(ctx, span); - if (ctx->Stencil.Enabled) { + if (ctx->Stencil._Enabled) { if (!_swrast_stencil_and_ztest_span(ctx, span)) { span->arrayMask = origArrayMask; return; @@ -866,7 +904,6 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) } } -#if FEATURE_ARB_occlusion_query if (ctx->Query.CurrentOcclusionObject) { /* update count of 'passed' fragments */ struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; @@ -874,7 +911,6 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) for (i = 0; i < span->end; i++) q->Result += span->array->mask[i]; } -#endif /* we have to wait until after occlusion to do this test */ if (ctx->Color.IndexMask == 0) { @@ -1211,7 +1247,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span) _swrast_exec_fragment_shader(ctx, span); } } - else if (ctx->Texture._EnabledUnits) { + else if (ctx->Texture._EnabledCoordUnits) { /* conventional texturing */ #if CHAN_BITS == 32 @@ -1250,7 +1286,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) void * const origRgba = span->array->rgba; const GLboolean shader = (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled); - const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; + const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits; struct gl_framebuffer *fb = ctx->DrawBuffer; /* @@ -1262,7 +1298,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) span->primitive == GL_LINE || span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); - ASSERT(span->end <= MAX_WIDTH); /* Fragment write masks */ if (span->arrayMask & SPAN_MASK) { @@ -1275,15 +1310,16 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) } /* Clip to window/scissor box */ - if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) { - if (!clip_span(ctx, span)) { - return; - } + if (!clip_span(ctx, span)) { + return; } + ASSERT(span->end <= MAX_WIDTH); + #ifdef DEBUG /* Make sure all fragments are within window bounds */ if (span->arrayMask & SPAN_XY) { + /* array of pixel locations */ GLuint i; for (i = 0; i < span->end; i++) { if (span->array->mask[i]) { @@ -1311,18 +1347,19 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) /* Do the alpha test */ if (ctx->Color.AlphaEnabled) { if (!_swrast_alpha_test(ctx, span)) { + /* all fragments failed test */ goto end; } } /* Stencil and Z testing */ - if (ctx->Stencil.Enabled || ctx->Depth.Test) { + if (ctx->Stencil._Enabled || ctx->Depth.Test) { if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z(ctx, span); - - if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) { + if (ctx->Stencil._Enabled) { /* Combined Z/stencil tests */ if (!_swrast_stencil_and_ztest_span(ctx, span)) { + /* all fragments failed test */ goto end; } } @@ -1331,12 +1368,12 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) ASSERT(ctx->Depth.Test); ASSERT(span->arrayMask & SPAN_Z); if (!_swrast_depth_test_span(ctx, span)) { + /* all fragments failed test */ goto end; } } } -#if FEATURE_ARB_occlusion_query if (ctx->Query.CurrentOcclusionObject) { /* update count of 'passed' fragments */ struct gl_query_object *q = ctx->Query.CurrentOcclusionObject; @@ -1344,12 +1381,12 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) for (i = 0; i < span->end; i++) q->Result += span->array->mask[i]; } -#endif /* We had to wait until now to check for glColorMask(0,0,0,0) because of * the occlusion test. */ if (colorMask == 0x0) { + /* no colors to write */ goto end; } @@ -1373,12 +1410,14 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) ASSERT(span->arrayMask & SPAN_RGBA); - if (!shader) { - /* Add base and specular colors */ - if (ctx->Fog.ColorSumEnabled || - (ctx->Light.Enabled && - ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { - add_specular(ctx, span); + if (span->primitive == GL_BITMAP || !swrast->SpecularVertexAdd) { + /* Add primary and specular (diffuse + specular) colors */ + if (!shader) { + if (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { + add_specular(ctx, span); + } } } @@ -1399,11 +1438,17 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) } /* - * Write to renderbuffers + * Write to renderbuffers. + * Depending on glDrawBuffer() state and the which color outputs are + * written by the fragment shader, we may either replicate one color to + * all renderbuffers or write a different color to each renderbuffer. + * multiFragOutputs=TRUE for the later case. */ { const GLuint numBuffers = fb->_NumColorDrawBuffers; - const GLboolean multiFragOutputs = numBuffers > 1; + const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; + const GLboolean multiFragOutputs = + (fp && fp->Base.OutputsWritten >= (1 << FRAG_RESULT_DATA0)); GLuint buf; for (buf = 0; buf < numBuffers; buf++) { diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index c4b47df58f..0eabae20e0 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.5 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. 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"), @@ -106,6 +107,9 @@ typedef struct sw_span /** Number of fragments in the span */ GLuint end; + /** for clipping left edge of spans */ + GLuint leftClip; + /** This flag indicates that mask[] array is effectively filled with ones */ GLboolean writeAll; @@ -165,6 +169,7 @@ do { \ (S).arrayMask = 0x0; \ (S).arrayAttribs = 0x0; \ (S).end = 0; \ + (S).leftClip = 0; \ (S).facing = 0; \ (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ } while (0) diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c index c925922463..e9e9d3a4f1 100644 --- a/src/mesa/swrast/s_stencil.c +++ b/src/mesa/swrast/s_stencil.c @@ -231,8 +231,9 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], GLubyte fail[MAX_WIDTH]; GLboolean allfail = GL_FALSE; GLuint i; - GLstencil r, s; const GLuint valueMask = ctx->Stencil.ValueMask[face]; + const GLstencil r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); + GLstencil s; ASSERT(n <= MAX_WIDTH); @@ -260,7 +261,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], allfail = GL_TRUE; break; case GL_LESS: - r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { s = (GLstencil) (stencil[i] & valueMask); @@ -279,7 +279,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], } break; case GL_LEQUAL: - r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { s = (GLstencil) (stencil[i] & valueMask); @@ -298,7 +297,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], } break; case GL_GREATER: - r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { s = (GLstencil) (stencil[i] & valueMask); @@ -317,7 +315,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], } break; case GL_GEQUAL: - r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { s = (GLstencil) (stencil[i] & valueMask); @@ -336,7 +333,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], } break; case GL_EQUAL: - r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { s = (GLstencil) (stencil[i] & valueMask); @@ -355,7 +351,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[], } break; case GL_NOTEQUAL: - r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask); for (i=0;i<n;i++) { if (mask[i]) { s = (GLstencil) (stencil[i] & valueMask); @@ -997,10 +992,12 @@ stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face ) GLboolean _swrast_stencil_and_ztest_span(GLcontext *ctx, SWspan *span) { + const GLuint face = (span->facing == 0) ? 0 : ctx->Stencil._BackFace; + if (span->arrayMask & SPAN_XY) - return stencil_and_ztest_pixels(ctx, span, span->facing); + return stencil_and_ztest_pixels(ctx, span, face); else - return stencil_and_ztest_span(ctx, span, span->facing); + return stencil_and_ztest_span(ctx, span, face); } diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c index 632d650007..889164b986 100644 --- a/src/mesa/swrast/s_texcombine.c +++ b/src/mesa/swrast/s_texcombine.c @@ -1,8 +1,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 7.5 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. 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"), @@ -28,116 +29,134 @@ #include "main/colormac.h" #include "main/image.h" #include "main/imports.h" -#include "main/macros.h" #include "main/pixel.h" +#include "shader/prog_instruction.h" #include "s_context.h" #include "s_texcombine.h" -#define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) ) -#define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) ) -#if CHAN_BITS == 32 -typedef GLfloat ChanTemp; -#else -typedef GLuint ChanTemp; -#endif +/** + * Pointer to array of float[4] + * This type makes the code below more concise and avoids a lot of casting. + */ +typedef float (*float4_array)[4]; + + +/** + * Return array of texels for given unit. + */ +static INLINE float4_array +get_texel_array(SWcontext *swrast, GLuint unit) +{ + return (float4_array) (swrast->TexelBuffer + unit * MAX_WIDTH * 4); +} + /** - * Do texture application for GL_ARB/EXT_texture_env_combine. - * This function also supports GL_{EXT,ARB}_texture_env_dot3 and - * GL_ATI_texture_env_combine3. Since "classic" texture environments are - * implemented using GL_ARB_texture_env_combine-like state, this same function - * is used for classic texture environment application as well. + * Do texture application for: + * GL_EXT_texture_env_combine + * GL_ARB_texture_env_combine + * GL_EXT_texture_env_dot3 + * GL_ARB_texture_env_dot3 + * GL_ATI_texture_env_combine3 + * GL_NV_texture_env_combine4 + * conventional GL texture env modes * * \param ctx rendering context - * \param textureUnit the texture unit to apply + * \param unit the texture combiner unit * \param n number of fragments to process (span width) * \param primary_rgba incoming fragment color array * \param texelBuffer pointer to texel colors for all texture units * - * \param rgba incoming colors, which get modified here + * \param rgba incoming/result fragment colors */ static void -texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, - CONST GLchan (*primary_rgba)[4], - CONST GLchan *texelBuffer, - GLchan (*rgba)[4] ) +texture_combine( GLcontext *ctx, GLuint unit, GLuint n, + const float4_array primary_rgba, + const GLfloat *texelBuffer, + GLchan (*rgbaChan)[4] ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]); - const GLchan (*argRGB [3])[4]; - const GLchan (*argA [3])[4]; - const GLuint RGBshift = textureUnit->_CurrentCombine->ScaleShiftRGB; - const GLuint Ashift = textureUnit->_CurrentCombine->ScaleShiftA; -#if CHAN_TYPE == GL_FLOAT - const GLchan RGBmult = (GLfloat) (1 << RGBshift); - const GLchan Amult = (GLfloat) (1 << Ashift); -#else - const GLint half = (CHAN_MAX + 1) / 2; -#endif - static const GLchan one[4] = { CHAN_MAX, CHAN_MAX, CHAN_MAX, CHAN_MAX }; - static const GLchan zero[4] = { 0, 0, 0, 0 }; - const GLuint numColorArgs = textureUnit->_CurrentCombine->_NumArgsRGB; - const GLuint numAlphaArgs = textureUnit->_CurrentCombine->_NumArgsA; - GLchan ccolor[3][MAX_WIDTH][4]; - GLuint i, j; - - ASSERT(ctx->Extensions.EXT_texture_env_combine || - ctx->Extensions.ARB_texture_env_combine); - ASSERT(SWRAST_CONTEXT(ctx)->_AnyTextureCombine); + const struct gl_tex_env_combine_state *combine = textureUnit->_CurrentCombine; + float4_array argRGB[MAX_COMBINER_TERMS]; + float4_array argA[MAX_COMBINER_TERMS]; + const GLfloat scaleRGB = (GLfloat) (1 << combine->ScaleShiftRGB); + const GLfloat scaleA = (GLfloat) (1 << combine->ScaleShiftA); + const GLuint numArgsRGB = combine->_NumArgsRGB; + const GLuint numArgsA = combine->_NumArgsA; + GLfloat ccolor[MAX_COMBINER_TERMS][MAX_WIDTH][4]; /* temp color buffers */ + GLfloat rgba[MAX_WIDTH][4]; + GLuint i, term; + + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = CHAN_TO_FLOAT(rgbaChan[i][RCOMP]); + rgba[i][GCOMP] = CHAN_TO_FLOAT(rgbaChan[i][GCOMP]); + rgba[i][BCOMP] = CHAN_TO_FLOAT(rgbaChan[i][BCOMP]); + rgba[i][ACOMP] = CHAN_TO_FLOAT(rgbaChan[i][ACOMP]); + } /* printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n", - textureUnit->_CurrentCombine->ModeRGB, - textureUnit->_CurrentCombine->ModeA, - textureUnit->_CurrentCombine->SourceRGB[0], - textureUnit->_CurrentCombine->SourceA[0], - textureUnit->_CurrentCombine->SourceRGB[1], - textureUnit->_CurrentCombine->SourceA[1]); + combine->ModeRGB, + combine->ModeA, + combine->SourceRGB[0], + combine->SourceA[0], + combine->SourceRGB[1], + combine->SourceA[1]); */ /* - * Do operand setup for up to 3 operands. Loop over the terms. + * Do operand setup for up to 4 operands. Loop over the terms. */ - for (j = 0; j < numColorArgs; j++) { - const GLenum srcRGB = textureUnit->_CurrentCombine->SourceRGB[j]; + for (term = 0; term < numArgsRGB; term++) { + const GLenum srcRGB = combine->SourceRGB[term]; + const GLenum operandRGB = combine->OperandRGB[term]; switch (srcRGB) { case GL_TEXTURE: - argRGB[j] = (const GLchan (*)[4]) - (texelBuffer + unit * (n * 4 * sizeof(GLchan))); + argRGB[term] = get_texel_array(swrast, unit); break; case GL_PRIMARY_COLOR: - argRGB[j] = primary_rgba; + argRGB[term] = primary_rgba; break; case GL_PREVIOUS: - argRGB[j] = (const GLchan (*)[4]) rgba; + argRGB[term] = rgba; break; case GL_CONSTANT: { - GLchan (*c)[4] = ccolor[j]; - GLchan red, green, blue, alpha; - UNCLAMPED_FLOAT_TO_CHAN(red, textureUnit->EnvColor[0]); - UNCLAMPED_FLOAT_TO_CHAN(green, textureUnit->EnvColor[1]); - UNCLAMPED_FLOAT_TO_CHAN(blue, textureUnit->EnvColor[2]); - UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]); + float4_array c = ccolor[term]; + GLfloat red = textureUnit->EnvColor[0]; + GLfloat green = textureUnit->EnvColor[1]; + GLfloat blue = textureUnit->EnvColor[2]; + GLfloat alpha = textureUnit->EnvColor[3]; for (i = 0; i < n; i++) { - c[i][RCOMP] = red; - c[i][GCOMP] = green; - c[i][BCOMP] = blue; - c[i][ACOMP] = alpha; + ASSIGN_4V(c[i], red, green, blue, alpha); } - argRGB[j] = (const GLchan (*)[4]) ccolor[j]; + argRGB[term] = ccolor[term]; } break; /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. */ case GL_ZERO: - argRGB[j] = & zero; + { + float4_array c = ccolor[term]; + for (i = 0; i < n; i++) { + ASSIGN_4V(c[i], 0.0F, 0.0F, 0.0F, 0.0F); + } + argRGB[term] = ccolor[term]; + } break; case GL_ONE: - argRGB[j] = & one; + { + float4_array c = ccolor[term]; + for (i = 0; i < n; i++) { + ASSIGN_4V(c[i], 1.0F, 1.0F, 1.0F, 1.0F); + } + argRGB[term] = ccolor[term]; + } break; default: /* ARB_texture_env_crossbar source */ @@ -146,76 +165,88 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, ASSERT(srcUnit < ctx->Const.MaxTextureUnits); if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) return; - argRGB[j] = (const GLchan (*)[4]) - (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan))); + argRGB[term] = get_texel_array(swrast, srcUnit); } } - if (textureUnit->_CurrentCombine->OperandRGB[j] != GL_SRC_COLOR) { - const GLchan (*src)[4] = argRGB[j]; - GLchan (*dst)[4] = ccolor[j]; + if (operandRGB != GL_SRC_COLOR) { + float4_array src = argRGB[term]; + float4_array dst = ccolor[term]; - /* point to new arg[j] storage */ - argRGB[j] = (const GLchan (*)[4]) ccolor[j]; + /* point to new arg[term] storage */ + argRGB[term] = ccolor[term]; - if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) { + switch (operandRGB) { + case GL_ONE_MINUS_SRC_COLOR: for (i = 0; i < n; i++) { - dst[i][RCOMP] = CHAN_MAX - src[i][RCOMP]; - dst[i][GCOMP] = CHAN_MAX - src[i][GCOMP]; - dst[i][BCOMP] = CHAN_MAX - src[i][BCOMP]; + dst[i][RCOMP] = 1.0F - src[i][RCOMP]; + dst[i][GCOMP] = 1.0F - src[i][GCOMP]; + dst[i][BCOMP] = 1.0F - src[i][BCOMP]; } - } - else if (textureUnit->_CurrentCombine->OperandRGB[j] == GL_SRC_ALPHA) { + break; + case GL_SRC_ALPHA: for (i = 0; i < n; i++) { - dst[i][RCOMP] = src[i][ACOMP]; - dst[i][GCOMP] = src[i][ACOMP]; + dst[i][RCOMP] = + dst[i][GCOMP] = dst[i][BCOMP] = src[i][ACOMP]; } - } - else { - ASSERT(textureUnit->_CurrentCombine->OperandRGB[j] ==GL_ONE_MINUS_SRC_ALPHA); + break; + case GL_ONE_MINUS_SRC_ALPHA: for (i = 0; i < n; i++) { - dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP]; - dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP]; - dst[i][BCOMP] = CHAN_MAX - src[i][ACOMP]; + dst[i][RCOMP] = + dst[i][GCOMP] = + dst[i][BCOMP] = 1.0F - src[i][ACOMP]; } + break; + default: + _mesa_problem(ctx, "Bad operandRGB"); } } } /* - * Set up the argA[i] pointers + * Set up the argA[term] pointers */ - for (j = 0; j < numAlphaArgs; j++) { - const GLenum srcA = textureUnit->_CurrentCombine->SourceA[j]; + for (term = 0; term < numArgsA; term++) { + const GLenum srcA = combine->SourceA[term]; + const GLenum operandA = combine->OperandA[term]; switch (srcA) { case GL_TEXTURE: - argA[j] = (const GLchan (*)[4]) - (texelBuffer + unit * (n * 4 * sizeof(GLchan))); + argA[term] = get_texel_array(swrast, unit); break; case GL_PRIMARY_COLOR: - argA[j] = primary_rgba; + argA[term] = primary_rgba; break; case GL_PREVIOUS: - argA[j] = (const GLchan (*)[4]) rgba; + argA[term] = rgba; break; case GL_CONSTANT: { - GLchan alpha, (*c)[4] = ccolor[j]; - UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]); + float4_array c = ccolor[term]; + GLfloat alpha = textureUnit->EnvColor[3]; for (i = 0; i < n; i++) c[i][ACOMP] = alpha; - argA[j] = (const GLchan (*)[4]) ccolor[j]; + argA[term] = ccolor[term]; } break; /* GL_ATI_texture_env_combine3 allows GL_ZERO & GL_ONE as sources. */ case GL_ZERO: - argA[j] = & zero; + { + float4_array c = ccolor[term]; + for (i = 0; i < n; i++) + c[i][ACOMP] = 0.0F; + argA[term] = ccolor[term]; + } break; case GL_ONE: - argA[j] = & one; + { + float4_array c = ccolor[term]; + for (i = 0; i < n; i++) + c[i][ACOMP] = 1.0F; + argA[term] = ccolor[term]; + } break; default: /* ARB_texture_env_crossbar source */ @@ -224,481 +255,251 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, ASSERT(srcUnit < ctx->Const.MaxTextureUnits); if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled) return; - argA[j] = (const GLchan (*)[4]) - (texelBuffer + srcUnit * (n * 4 * sizeof(GLchan))); + argA[term] = get_texel_array(swrast, srcUnit); } } - if (textureUnit->_CurrentCombine->OperandA[j] == GL_ONE_MINUS_SRC_ALPHA) { - const GLchan (*src)[4] = argA[j]; - GLchan (*dst)[4] = ccolor[j]; - argA[j] = (const GLchan (*)[4]) ccolor[j]; + if (operandA == GL_ONE_MINUS_SRC_ALPHA) { + float4_array src = argA[term]; + float4_array dst = ccolor[term]; + argA[term] = ccolor[term]; for (i = 0; i < n; i++) { - dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP]; + dst[i][ACOMP] = 1.0F - src[i][ACOMP]; } } } - /* - * Do the texture combine. - */ - switch (textureUnit->_CurrentCombine->ModeRGB) { + /* RGB channel combine */ + { + float4_array arg0 = argRGB[0]; + float4_array arg1 = argRGB[1]; + float4_array arg2 = argRGB[2]; + float4_array arg3 = argRGB[3]; + + switch (combine->ModeRGB) { case GL_REPLACE: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; - if (RGBshift) { - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][RCOMP] = arg0[i][RCOMP] * RGBmult; - rgba[i][GCOMP] = arg0[i][GCOMP] * RGBmult; - rgba[i][BCOMP] = arg0[i][BCOMP] * RGBmult; -#else - GLuint r = (GLuint) arg0[i][RCOMP] << RGBshift; - GLuint g = (GLuint) arg0[i][GCOMP] << RGBshift; - GLuint b = (GLuint) arg0[i][BCOMP] << RGBshift; - rgba[i][RCOMP] = MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = MIN2(b, CHAN_MAX); -#endif - } - } - else { - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = arg0[i][RCOMP]; - rgba[i][GCOMP] = arg0[i][GCOMP]; - rgba[i][BCOMP] = arg0[i][BCOMP]; - } - } + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = arg0[i][RCOMP] * scaleRGB; + rgba[i][GCOMP] = arg0[i][GCOMP] * scaleRGB; + rgba[i][BCOMP] = arg0[i][BCOMP] * scaleRGB; } break; case GL_MODULATE: - { - 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 = CHAN_BITS - RGBshift; -#endif - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * RGBmult; - rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * RGBmult; - rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * RGBmult; -#else - GLuint r = PROD(arg0[i][RCOMP], arg1[i][RCOMP]) >> shift; - GLuint g = PROD(arg0[i][GCOMP], arg1[i][GCOMP]) >> shift; - GLuint b = PROD(arg0[i][BCOMP], arg1[i][BCOMP]) >> shift; - rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * scaleRGB; + rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * scaleRGB; + rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * scaleRGB; } break; case GL_ADD: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; - const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + if (textureUnit->EnvMode == GL_COMBINE4_NV) { + /* (a * b) + (c * d) */ for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * RGBmult; - rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * RGBmult; - rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * RGBmult; -#else - GLint r = ((GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP]) << RGBshift; - GLint g = ((GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP]) << RGBshift; - GLint b = ((GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP]) << RGBshift; - rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); -#endif + rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + + arg2[i][RCOMP] * arg3[i][RCOMP]) * scaleRGB; + rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + + arg2[i][GCOMP] * arg3[i][GCOMP]) * scaleRGB; + rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + + arg2[i][BCOMP] * arg3[i][BCOMP]) * scaleRGB; + } + } + else { + /* 2-term addition */ + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * scaleRGB; + rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * scaleRGB; + rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * scaleRGB; } } break; case GL_ADD_SIGNED: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; - const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1]; + if (textureUnit->EnvMode == GL_COMBINE4_NV) { + /* (a * b) + (c * d) - 0.5 */ for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5) * RGBmult; - rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * RGBmult; - rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * RGBmult; -#else - GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] -half; - GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] -half; - GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] -half; - r = (r < 0) ? 0 : r << RGBshift; - g = (g < 0) ? 0 : g << RGBshift; - b = (b < 0) ? 0 : b << RGBshift; - rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); -#endif + rgba[i][RCOMP] = (arg0[i][RCOMP] * arg1[i][RCOMP] + + arg2[i][RCOMP] * arg3[i][RCOMP] - 0.5) * scaleRGB; + rgba[i][GCOMP] = (arg0[i][GCOMP] * arg1[i][GCOMP] + + arg2[i][GCOMP] * arg3[i][GCOMP] - 0.5) * scaleRGB; + rgba[i][BCOMP] = (arg0[i][BCOMP] * arg1[i][BCOMP] + + arg2[i][BCOMP] * arg3[i][BCOMP] - 0.5) * scaleRGB; } } - break; - case GL_INTERPOLATE: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; - 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 = CHAN_BITS - RGBshift; -#endif + else { for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] + - arg1[i][RCOMP] * (CHAN_MAXF - arg2[i][RCOMP])) * RGBmult; - rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] + - arg1[i][GCOMP] * (CHAN_MAXF - arg2[i][GCOMP])) * RGBmult; - rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] + - arg1[i][BCOMP] * (CHAN_MAXF - arg2[i][BCOMP])) * RGBmult; -#else - GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP]) - + PROD(arg1[i][RCOMP], CHAN_MAX - arg2[i][RCOMP])) - >> shift; - GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP]) - + PROD(arg1[i][GCOMP], CHAN_MAX - arg2[i][GCOMP])) - >> shift; - GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP]) - + PROD(arg1[i][BCOMP], CHAN_MAX - arg2[i][BCOMP])) - >> shift; - rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); -#endif + rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5) * scaleRGB; + rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * scaleRGB; + rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * scaleRGB; } } break; + case GL_INTERPOLATE: + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] + + arg1[i][RCOMP] * (1.0F - arg2[i][RCOMP])) * scaleRGB; + rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] + + arg1[i][GCOMP] * (1.0F - arg2[i][GCOMP])) * scaleRGB; + rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] + + arg1[i][BCOMP] * (1.0F - arg2[i][BCOMP])) * scaleRGB; + } + break; case GL_SUBTRACT: - { - 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 - rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * RGBmult; - rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * RGBmult; - rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * RGBmult; -#else - GLint r = ((GLint) arg0[i][RCOMP] - (GLint) arg1[i][RCOMP]) << RGBshift; - GLint g = ((GLint) arg0[i][GCOMP] - (GLint) arg1[i][GCOMP]) << RGBshift; - GLint b = ((GLint) arg0[i][BCOMP] - (GLint) arg1[i][BCOMP]) << RGBshift; - rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * scaleRGB; + rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * scaleRGB; + rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * scaleRGB; } 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; - dot = CLAMP(dot, 0.0F, CHAN_MAXF); -#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; - dot = CLAMP(dot, 0, CHAN_MAX); -#endif - rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; - } + /* Do not scale the result by 1 2 or 4 */ + for (i = 0; i < n; i++) { + GLfloat 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; + dot = CLAMP(dot, 0.0F, 1.0F); + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; } break; case GL_DOT3_RGB: case GL_DOT3_RGBA: - { - /* 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]; - 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 * RGBmult; - dot = CLAMP(dot, 0.0, CHAN_MAXF); -#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; - dot <<= RGBshift; - dot = CLAMP(dot, 0, CHAN_MAX); -#endif - rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot; - } + /* DO scale the result by 1 2 or 4 */ + for (i = 0; i < n; i++) { + GLfloat 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 * scaleRGB; + dot = CLAMP(dot, 0.0, 1.0F); + rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; } break; case GL_MODULATE_ADD_ATI: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; - 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 = CHAN_BITS - RGBshift; -#endif - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP]) * RGBmult; - rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP]) * RGBmult; - rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP]) * RGBmult; -#else - GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP]) - + ((GLuint) arg1[i][RCOMP] << CHAN_BITS)) >> shift; - GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP]) - + ((GLuint) arg1[i][GCOMP] << CHAN_BITS)) >> shift; - GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP]) - + ((GLuint) arg1[i][BCOMP] << CHAN_BITS)) >> shift; - rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + + arg1[i][RCOMP]) * scaleRGB; + rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + + arg1[i][GCOMP]) * scaleRGB; + rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + + arg1[i][BCOMP]) * scaleRGB; } break; case GL_MODULATE_SIGNED_ADD_ATI: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; - 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 = CHAN_BITS - RGBshift; -#endif - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + arg1[i][RCOMP] - 0.5) * RGBmult; - rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + arg1[i][GCOMP] - 0.5) * RGBmult; - rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + arg1[i][BCOMP] - 0.5) * RGBmult; -#else - GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP]) - + (((GLint) arg1[i][RCOMP] - half) << CHAN_BITS)) - >> shift; - GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP]) - + (((GLint) arg1[i][GCOMP] - half) << CHAN_BITS)) - >> shift; - GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP]) - + (((GLint) arg1[i][BCOMP] - half) << CHAN_BITS)) - >> shift; - rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) + + arg1[i][RCOMP] - 0.5) * scaleRGB; + rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) + + arg1[i][GCOMP] - 0.5) * scaleRGB; + rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) + + arg1[i][BCOMP] - 0.5) * scaleRGB; } break; case GL_MODULATE_SUBTRACT_ATI: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0]; - 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 = CHAN_BITS - RGBshift; -#endif - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - arg1[i][RCOMP]) * RGBmult; - rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - arg1[i][GCOMP]) * RGBmult; - rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - arg1[i][BCOMP]) * RGBmult; -#else - GLint r = (S_PROD(arg0[i][RCOMP], arg2[i][RCOMP]) - - ((GLint) arg1[i][RCOMP] << CHAN_BITS)) - >> shift; - GLint g = (S_PROD(arg0[i][GCOMP], arg2[i][GCOMP]) - - ((GLint) arg1[i][GCOMP] << CHAN_BITS)) - >> shift; - GLint b = (S_PROD(arg0[i][BCOMP], arg2[i][BCOMP]) - - ((GLint) arg1[i][BCOMP] << CHAN_BITS)) - >> shift; - rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX); - rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX); - rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][RCOMP] = ((arg0[i][RCOMP] * arg2[i][RCOMP]) - + arg1[i][RCOMP]) * scaleRGB; + rgba[i][GCOMP] = ((arg0[i][GCOMP] * arg2[i][GCOMP]) - + arg1[i][GCOMP]) * scaleRGB; + rgba[i][BCOMP] = ((arg0[i][BCOMP] * arg2[i][BCOMP]) - + arg1[i][BCOMP]) * scaleRGB; } break; + case GL_BUMP_ENVMAP_ATI: + /* this produces a fixed rgba color, and the coord calc is done elsewhere */ + for (i = 0; i < n; i++) { + /* rgba result is 0,0,0,1 */ + rgba[i][RCOMP] = 0.0; + rgba[i][GCOMP] = 0.0; + rgba[i][BCOMP] = 0.0; + rgba[i][ACOMP] = 1.0; + } + return; /* no alpha processing */ default: _mesa_problem(ctx, "invalid combine mode"); + } } - switch (textureUnit->_CurrentCombine->ModeA) { + /* Alpha channel combine */ + { + float4_array arg0 = argA[0]; + float4_array arg1 = argA[1]; + float4_array arg2 = argA[2]; + float4_array arg3 = argA[3]; + + switch (combine->ModeA) { case GL_REPLACE: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; - if (Ashift) { - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - GLchan a = arg0[i][ACOMP] * Amult; -#else - GLuint a = (GLuint) arg0[i][ACOMP] << Ashift; -#endif - rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); - } - } - else { - for (i = 0; i < n; i++) { - rgba[i][ACOMP] = arg0[i][ACOMP]; - } - } + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = arg0[i][ACOMP] * scaleA; } break; case GL_MODULATE: - { - 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 = CHAN_BITS - Ashift; -#endif - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * Amult; -#else - GLuint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift); - rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * scaleA; } break; case GL_ADD: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; - const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; + if (textureUnit->EnvMode == GL_COMBINE4_NV) { + /* (a * b) + (c * d) */ for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * Amult; -#else - GLint a = ((GLint) arg0[i][ACOMP] + arg1[i][ACOMP]) << Ashift; - rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); -#endif + rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + + arg2[i][ACOMP] * arg3[i][ACOMP]) * scaleA; + } + } + else { + /* two-term add */ + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * scaleA; } } break; case GL_ADD_SIGNED: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; - const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; + if (textureUnit->EnvMode == GL_COMBINE4_NV) { + /* (a * b) + (c * d) - 0.5 */ + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = (arg0[i][ACOMP] * arg1[i][ACOMP] + + arg2[i][ACOMP] * arg3[i][ACOMP] - + 0.5) * scaleA; + } + } + else { + /* a + b - 0.5 */ for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * Amult; -#else - GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] -half; - a = (a < 0) ? 0 : a << Ashift; - rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); -#endif + rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * scaleA; } } break; case GL_INTERPOLATE: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; - 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 = CHAN_BITS - Ashift; -#endif - for (i=0; i<n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] + - arg1[i][ACOMP] * (CHAN_MAXF - arg2[i][ACOMP])) - * Amult; -#else - GLuint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP]) - + PROD(arg1[i][ACOMP], CHAN_MAX - arg2[i][ACOMP])) - >> shift; - rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] + + arg1[i][ACOMP] * (1.0F - arg2[i][ACOMP])) + * scaleA; } break; case GL_SUBTRACT: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; - const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1]; - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * Amult; -#else - GLint a = ((GLint) arg0[i][ACOMP] - (GLint) arg1[i][ACOMP]) << Ashift; - rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * scaleA; } break; case GL_MODULATE_ADD_ATI: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; - 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 = CHAN_BITS - Ashift; -#endif - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP]) * Amult; -#else - GLint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP]) - + ((GLuint) arg1[i][ACOMP] << CHAN_BITS)) - >> shift; - rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + + arg1[i][ACOMP]) * scaleA; } break; case GL_MODULATE_SIGNED_ADD_ATI: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; - 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 = CHAN_BITS - Ashift; -#endif - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + arg1[i][ACOMP] - 0.5F) * Amult; -#else - GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP]) - + (((GLint) arg1[i][ACOMP] - half) << CHAN_BITS)) - >> shift; - rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + + arg1[i][ACOMP] - 0.5F) * scaleA; } break; case GL_MODULATE_SUBTRACT_ATI: - { - const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0]; - 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 = CHAN_BITS - Ashift; -#endif - for (i = 0; i < n; i++) { -#if CHAN_TYPE == GL_FLOAT - rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) - arg1[i][ACOMP]) * Amult; -#else - GLint a = (S_PROD(arg0[i][ACOMP], arg2[i][ACOMP]) - - ((GLint) arg1[i][ACOMP] << CHAN_BITS)) - >> shift; - rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX); -#endif - } + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = ((arg0[i][ACOMP] * arg2[i][ACOMP]) + - arg1[i][ACOMP]) * scaleA; } break; default: _mesa_problem(ctx, "invalid combine mode"); + } } /* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining. @@ -706,370 +507,52 @@ texture_combine( const GLcontext *ctx, GLuint unit, GLuint n, * were written such that the GL_COMBINE_ALPHA value could be set to * GL_DOT3. */ - if (textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT || - textureUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) { + if (combine->ModeRGB == GL_DOT3_RGBA_EXT || + combine->ModeRGB == GL_DOT3_RGBA) { for (i = 0; i < n; i++) { rgba[i][ACOMP] = rgba[i][RCOMP]; } } + + for (i = 0; i < n; i++) { + UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][RCOMP], rgba[i][RCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][GCOMP], rgba[i][GCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][BCOMP], rgba[i][BCOMP]); + UNCLAMPED_FLOAT_TO_CHAN(rgbaChan[i][ACOMP], rgba[i][ACOMP]); + } } -#undef PROD /** - * 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 - * primary_rgba - primary colors (may alias rgba for single texture) - * texels - array of texel colors - * InOut: rgba - incoming fragment colors modified by texel colors - * according to the texture environment mode. + * Apply X/Y/Z/W/0/1 swizzle to an array of colors/texels. + * See GL_EXT_texture_swizzle. */ static void -texture_apply( const GLcontext *ctx, - const struct gl_texture_unit *texUnit, - GLuint n, - CONST GLchan primary_rgba[][4], CONST GLchan texel[][4], - GLchan rgba[][4] ) +swizzle_texels(GLuint swizzle, GLuint count, float4_array texels) { - GLint baseLevel; + const GLuint swzR = GET_SWZ(swizzle, 0); + const GLuint swzG = GET_SWZ(swizzle, 1); + const GLuint swzB = GET_SWZ(swizzle, 2); + const GLuint swzA = GET_SWZ(swizzle, 3); + GLfloat vector[6]; GLuint i; - GLchan Rc, Gc, Bc, Ac; - GLenum format; - (void) primary_rgba; - - ASSERT(texUnit); - ASSERT(texUnit->_Current); - - baseLevel = texUnit->_Current->BaseLevel; - ASSERT(texUnit->_Current->Image[0][baseLevel]); - - format = texUnit->_Current->Image[0][baseLevel]->_BaseFormat; - - if (format == GL_COLOR_INDEX || format == GL_YCBCR_MESA) { - format = GL_RGBA; /* a bit of a hack */ - } - else if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) { - format = texUnit->_Current->DepthMode; - } - - switch (texUnit->EnvMode) { - case GL_REPLACE: - switch (format) { - case GL_ALPHA: - for (i=0;i<n;i++) { - /* Cv = Cf */ - /* Av = At */ - rgba[i][ACOMP] = texel[i][ACOMP]; - } - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) { - /* Cv = Lt */ - GLchan Lt = texel[i][RCOMP]; - rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt; - /* Av = Af */ - } - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - GLchan Lt = texel[i][RCOMP]; - /* Cv = Lt */ - rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt; - /* Av = At */ - rgba[i][ACOMP] = texel[i][ACOMP]; - } - break; - case GL_INTENSITY: - for (i=0;i<n;i++) { - /* Cv = It */ - GLchan It = texel[i][RCOMP]; - rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It; - /* Av = It */ - rgba[i][ACOMP] = It; - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - /* Cv = Ct */ - rgba[i][RCOMP] = texel[i][RCOMP]; - rgba[i][GCOMP] = texel[i][GCOMP]; - rgba[i][BCOMP] = texel[i][BCOMP]; - /* Av = Af */ - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - /* Cv = Ct */ - rgba[i][RCOMP] = texel[i][RCOMP]; - rgba[i][GCOMP] = texel[i][GCOMP]; - rgba[i][BCOMP] = texel[i][BCOMP]; - /* Av = At */ - rgba[i][ACOMP] = texel[i][ACOMP]; - } - break; - default: - _mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply"); - return; - } - break; - - case GL_MODULATE: - switch (format) { - case GL_ALPHA: - for (i=0;i<n;i++) { - /* Cv = Cf */ - /* Av = AfAt */ - rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); - } - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) { - /* Cv = LtCf */ - GLchan Lt = texel[i][RCOMP]; - rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt ); - rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt ); - rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt ); - /* Av = Af */ - } - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - /* Cv = CfLt */ - GLchan Lt = texel[i][RCOMP]; - rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt ); - rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt ); - rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt ); - /* Av = AfAt */ - rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); - } - break; - case GL_INTENSITY: - for (i=0;i<n;i++) { - /* Cv = CfIt */ - GLchan It = texel[i][RCOMP]; - rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], It ); - rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], It ); - rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], It ); - /* Av = AfIt */ - rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], It ); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - /* Cv = CfCt */ - rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] ); - rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] ); - rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] ); - /* Av = Af */ - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - /* Cv = CfCt */ - rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] ); - rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] ); - rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] ); - /* Av = AfAt */ - rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] ); - } - break; - default: - _mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply"); - return; - } - break; - - case GL_DECAL: - switch (format) { - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - /* undefined */ - break; - case GL_RGB: - for (i=0;i<n;i++) { - /* Cv = Ct */ - rgba[i][RCOMP] = texel[i][RCOMP]; - rgba[i][GCOMP] = texel[i][GCOMP]; - rgba[i][BCOMP] = texel[i][BCOMP]; - /* Av = Af */ - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - /* Cv = Cf(1-At) + CtAt */ - GLchan t = texel[i][ACOMP], s = CHAN_MAX - t; - rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(texel[i][RCOMP],t); - rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(texel[i][GCOMP],t); - rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(texel[i][BCOMP],t); - /* Av = Af */ - } - break; - default: - _mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply"); - return; - } - break; - - case GL_BLEND: - UNCLAMPED_FLOAT_TO_CHAN(Rc, texUnit->EnvColor[0]); - UNCLAMPED_FLOAT_TO_CHAN(Gc, texUnit->EnvColor[1]); - UNCLAMPED_FLOAT_TO_CHAN(Bc, texUnit->EnvColor[2]); - UNCLAMPED_FLOAT_TO_CHAN(Ac, texUnit->EnvColor[3]); - switch (format) { - case GL_ALPHA: - for (i=0;i<n;i++) { - /* Cv = Cf */ - /* Av = AfAt */ - rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); - } - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) { - /* Cv = Cf(1-Lt) + CcLt */ - GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt; - rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt); - rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt); - rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt); - /* Av = Af */ - } - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - /* Cv = Cf(1-Lt) + CcLt */ - GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt; - rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt); - rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt); - rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt); - /* Av = AfAt */ - rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]); - } - break; - case GL_INTENSITY: - for (i=0;i<n;i++) { - /* Cv = Cf(1-It) + CcIt */ - GLchan It = texel[i][RCOMP], s = CHAN_MAX - It; - rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, It); - rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, It); - rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, It); - /* Av = Af(1-It) + Ac*It */ - rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], s) + CHAN_PRODUCT(Ac, It); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - /* Cv = Cf(1-Ct) + CcCt */ - rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]); - rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]); - rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]); - /* Av = Af */ - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - /* Cv = Cf(1-Ct) + CcCt */ - rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]); - rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]); - rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]); - /* Av = AfAt */ - rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]); - } - break; - default: - _mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply"); - return; - } - break; - - /* XXX don't clamp results if GLchan is float??? */ - - case GL_ADD: /* GL_EXT_texture_add_env */ - switch (format) { - case GL_ALPHA: - for (i=0;i<n;i++) { - /* Rv = Rf */ - /* Gv = Gf */ - /* Bv = Bf */ - rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); - } - break; - case GL_LUMINANCE: - for (i=0;i<n;i++) { - ChanTemp Lt = texel[i][RCOMP]; - ChanTemp r = rgba[i][RCOMP] + Lt; - ChanTemp g = rgba[i][GCOMP] + Lt; - ChanTemp b = rgba[i][BCOMP] + Lt; - rgba[i][RCOMP] = MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = MIN2(b, CHAN_MAX); - /* Av = Af */ - } - break; - case GL_LUMINANCE_ALPHA: - for (i=0;i<n;i++) { - ChanTemp Lt = texel[i][RCOMP]; - ChanTemp r = rgba[i][RCOMP] + Lt; - ChanTemp g = rgba[i][GCOMP] + Lt; - ChanTemp b = rgba[i][BCOMP] + Lt; - rgba[i][RCOMP] = MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = MIN2(b, CHAN_MAX); - rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); - } - break; - case GL_INTENSITY: - for (i=0;i<n;i++) { - GLchan It = texel[i][RCOMP]; - ChanTemp r = rgba[i][RCOMP] + It; - ChanTemp g = rgba[i][GCOMP] + It; - ChanTemp b = rgba[i][BCOMP] + It; - ChanTemp a = rgba[i][ACOMP] + It; - rgba[i][RCOMP] = MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = MIN2(b, CHAN_MAX); - rgba[i][ACOMP] = MIN2(a, CHAN_MAX); - } - break; - case GL_RGB: - for (i=0;i<n;i++) { - ChanTemp r = rgba[i][RCOMP] + texel[i][RCOMP]; - ChanTemp g = rgba[i][GCOMP] + texel[i][GCOMP]; - ChanTemp b = rgba[i][BCOMP] + texel[i][BCOMP]; - rgba[i][RCOMP] = MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = MIN2(b, CHAN_MAX); - /* Av = Af */ - } - break; - case GL_RGBA: - for (i=0;i<n;i++) { - ChanTemp r = rgba[i][RCOMP] + texel[i][RCOMP]; - ChanTemp g = rgba[i][GCOMP] + texel[i][GCOMP]; - ChanTemp b = rgba[i][BCOMP] + texel[i][BCOMP]; - rgba[i][RCOMP] = MIN2(r, CHAN_MAX); - rgba[i][GCOMP] = MIN2(g, CHAN_MAX); - rgba[i][BCOMP] = MIN2(b, CHAN_MAX); - rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]); - } - break; - default: - _mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply"); - return; - } - break; - default: - _mesa_problem(ctx, "Bad env mode in texture_apply"); - return; + vector[SWIZZLE_ZERO] = 0; + vector[SWIZZLE_ONE] = 1.0F; + + for (i = 0; i < count; i++) { + vector[SWIZZLE_X] = texels[i][0]; + vector[SWIZZLE_Y] = texels[i][1]; + vector[SWIZZLE_Z] = texels[i][2]; + vector[SWIZZLE_W] = texels[i][3]; + texels[i][RCOMP] = vector[swzR]; + texels[i][GCOMP] = vector[swzG]; + texels[i][BCOMP] = vector[swzB]; + texels[i][ACOMP] = vector[swzA]; } } - /** * Apply texture mapping to a span of fragments. */ @@ -1077,31 +560,99 @@ void _swrast_texture_span( GLcontext *ctx, SWspan *span ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLchan primary_rgba[MAX_WIDTH][4]; + GLfloat primary_rgba[MAX_WIDTH][4]; GLuint unit; - ASSERT(span->end < MAX_WIDTH); + ASSERT(span->end <= MAX_WIDTH); /* * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR) */ - if (swrast->_AnyTextureCombine) - MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan)); + if (swrast->_TextureCombinePrimary) { + GLuint i; + for (i = 0; i < span->end; i++) { + primary_rgba[i][RCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]); + primary_rgba[i][GCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); + primary_rgba[i][BCOMP] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); + primary_rgba[i][ACOMP] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]); + } + } + + /* First must sample all bump maps */ + for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + + if (texUnit->_ReallyEnabled && + texUnit->_CurrentCombine->ModeRGB == GL_BUMP_ENVMAP_ATI) { + const GLfloat (*texcoords)[4] = (const GLfloat (*)[4]) + span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; + float4_array targetcoords = + span->array->attribs[FRAG_ATTRIB_TEX0 + + ctx->Texture.Unit[unit].BumpTarget - GL_TEXTURE0]; + + const struct gl_texture_object *curObj = texUnit->_Current; + GLfloat *lambda = span->array->lambda[unit]; + float4_array texels = get_texel_array(swrast, unit); + GLuint i; + GLfloat rotMatrix00 = ctx->Texture.Unit[unit].RotMatrix[0]; + GLfloat rotMatrix01 = ctx->Texture.Unit[unit].RotMatrix[1]; + GLfloat rotMatrix10 = ctx->Texture.Unit[unit].RotMatrix[2]; + GLfloat rotMatrix11 = ctx->Texture.Unit[unit].RotMatrix[3]; + + /* adjust texture lod (lambda) */ + if (span->arrayMask & SPAN_LAMBDA) { + if (texUnit->LodBias + curObj->LodBias != 0.0F) { + /* apply LOD bias, but don't clamp yet */ + const GLfloat bias = CLAMP(texUnit->LodBias + curObj->LodBias, + -ctx->Const.MaxTextureLodBias, + ctx->Const.MaxTextureLodBias); + GLuint i; + for (i = 0; i < span->end; i++) { + lambda[i] += bias; + } + } + + if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) { + /* apply LOD clamping to lambda */ + const GLfloat min = curObj->MinLod; + const GLfloat max = curObj->MaxLod; + GLuint i; + for (i = 0; i < span->end; i++) { + GLfloat l = lambda[i]; + lambda[i] = CLAMP(l, min, max); + } + } + } + + /* Sample the texture (span->end = number of fragments) */ + swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end, + texcoords, lambda, texels ); + + /* manipulate the span values of the bump target + not sure this can work correctly even ignoring + the problem that channel is unsigned */ + for (i = 0; i < span->end; i++) { + targetcoords[i][0] += (texels[i][0] * rotMatrix00 + texels[i][1] * + rotMatrix01) / targetcoords[i][3]; + targetcoords[i][1] += (texels[i][0] * rotMatrix10 + texels[i][1] * + rotMatrix11) / targetcoords[i][3]; + } + } + } /* * 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 GLfloat (*texcoords)[4] - = (const GLfloat (*)[4]) + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + if (texUnit->_ReallyEnabled && + texUnit->_CurrentCombine->ModeRGB != GL_BUMP_ENVMAP_ATI) { + const GLfloat (*texcoords)[4] = (const GLfloat (*)[4]) span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; const struct gl_texture_object *curObj = texUnit->_Current; GLfloat *lambda = span->array->lambda[unit]; - GLchan (*texels)[4] = (GLchan (*)[4]) - (swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan))); + float4_array texels = get_texel_array(swrast, unit); /* adjust texture lod (lambda) */ if (span->arrayMask & SPAN_LAMBDA) { @@ -1134,13 +685,12 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span ) /* GL_SGI_texture_color_table */ if (texUnit->ColorTableEnabled) { -#if CHAN_TYPE == GL_UNSIGNED_BYTE - _mesa_lookup_rgba_ubyte(&texUnit->ColorTable, span->end, texels); -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - _mesa_lookup_rgba_ubyte(&texUnit->ColorTable, span->end, texels); -#else _mesa_lookup_rgba_float(&texUnit->ColorTable, span->end, texels); -#endif + } + + /* GL_EXT_texture_swizzle */ + if (curObj->_Swizzle != SWIZZLE_NOOP) { + swizzle_texels(curObj->_Swizzle, span->end, texels); } } } @@ -1151,22 +701,10 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span ) */ 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->_CurrentCombine != &texUnit->_EnvMode ) { - texture_combine( ctx, unit, span->end, - (CONST GLchan (*)[4]) primary_rgba, - swrast->TexelBuffer, - span->array->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->array->rgba ); - } + texture_combine( ctx, unit, span->end, + primary_rgba, + swrast->TexelBuffer, + span->array->rgba ); } } } diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index a095b255ab..6b1f934647 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -43,18 +43,11 @@ #define FRAC(f) ((f) - IFLOOR(f)) -/** - * Constants for integer linear interpolation. - */ -#define ILERP_SCALE 65536.0F -#define ILERP_SHIFT 16 - /** - * Linear interpolation macros + * Linear interpolation macro */ #define LERP(T, A, B) ( (A) + (T) * ((B) - (A)) ) -#define ILERP(IT, A, B) ( (A) + (((IT) * ((B) - (A))) >> ILERP_SHIFT) ) /** @@ -76,21 +69,6 @@ lerp_2d(GLfloat a, GLfloat b, /** - * Do 2D/biliner interpolation of integer values. - * \sa lerp_2d - */ -static INLINE GLint -ilerp_2d(GLint ia, GLint ib, - GLint v00, GLint v10, GLint v01, GLint v11) -{ - /* fixed point interpolants in [0, ILERP_SCALE] */ - const GLint temp0 = ILERP(ia, v00, v10); - const GLint temp1 = ILERP(ia, v01, v11); - return ILERP(ib, temp0, temp1); -} - - -/** * Do 3D/trilinear interpolation of float values. * \sa lerp_2d */ @@ -110,50 +88,15 @@ lerp_3d(GLfloat a, GLfloat b, GLfloat c, /** - * Do 3D/trilinear interpolation of integer values. - * \sa lerp_2d - */ -static INLINE GLint -ilerp_3d(GLint ia, GLint ib, GLint ic, - GLint v000, GLint v100, GLint v010, GLint v110, - GLint v001, GLint v101, GLint v011, GLint v111) -{ - /* fixed point interpolants in [0, ILERP_SCALE] */ - const GLint temp00 = ILERP(ia, v000, v100); - const GLint temp10 = ILERP(ia, v010, v110); - const GLint temp01 = ILERP(ia, v001, v101); - const GLint temp11 = ILERP(ia, v011, v111); - const GLint temp0 = ILERP(ib, temp00, temp10); - const GLint temp1 = ILERP(ib, temp01, temp11); - return ILERP(ic, temp0, temp1); -} - - -/** * Do linear interpolation of colors. */ static INLINE void -lerp_rgba(GLchan result[4], GLfloat t, const GLchan a[4], const GLchan b[4]) +lerp_rgba(GLfloat result[4], GLfloat t, const GLfloat a[4], const GLfloat b[4]) { -#if CHAN_TYPE == GL_FLOAT result[0] = LERP(t, a[0], b[0]); result[1] = LERP(t, a[1], b[1]); result[2] = LERP(t, a[2], b[2]); result[3] = LERP(t, a[3], b[3]); -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - result[0] = (GLchan) (LERP(t, a[0], b[0]) + 0.5); - result[1] = (GLchan) (LERP(t, a[1], b[1]) + 0.5); - result[2] = (GLchan) (LERP(t, a[2], b[2]) + 0.5); - result[3] = (GLchan) (LERP(t, a[3], b[3]) + 0.5); -#else - /* fixed point interpolants in [0, ILERP_SCALE] */ - const GLint it = IROUND_POS(t * ILERP_SCALE); - ASSERT(CHAN_TYPE == GL_UNSIGNED_BYTE); - result[0] = ILERP(it, a[0], b[0]); - result[1] = ILERP(it, a[1], b[1]); - result[2] = ILERP(it, a[2], b[2]); - result[3] = ILERP(it, a[3], b[3]); -#endif } @@ -161,29 +104,14 @@ lerp_rgba(GLchan result[4], GLfloat t, const GLchan a[4], const GLchan b[4]) * Do bilinear interpolation of colors. */ static INLINE void -lerp_rgba_2d(GLchan result[4], GLfloat a, GLfloat b, - const GLchan t00[4], const GLchan t10[4], - const GLchan t01[4], const GLchan t11[4]) +lerp_rgba_2d(GLfloat result[4], GLfloat a, GLfloat b, + const GLfloat t00[4], const GLfloat t10[4], + const GLfloat t01[4], const GLfloat t11[4]) { -#if CHAN_TYPE == GL_FLOAT result[0] = lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]); result[1] = lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]); result[2] = lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]); result[3] = lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]); -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - result[0] = (GLchan) (lerp_2d(a, b, t00[0], t10[0], t01[0], t11[0]) + 0.5); - result[1] = (GLchan) (lerp_2d(a, b, t00[1], t10[1], t01[1], t11[1]) + 0.5); - result[2] = (GLchan) (lerp_2d(a, b, t00[2], t10[2], t01[2], t11[2]) + 0.5); - result[3] = (GLchan) (lerp_2d(a, b, t00[3], t10[3], t01[3], t11[3]) + 0.5); -#else - const GLint ia = IROUND_POS(a * ILERP_SCALE); - const GLint ib = IROUND_POS(b * ILERP_SCALE); - ASSERT(CHAN_TYPE == GL_UNSIGNED_BYTE); - result[0] = ilerp_2d(ia, ib, t00[0], t10[0], t01[0], t11[0]); - result[1] = ilerp_2d(ia, ib, t00[1], t10[1], t01[1], t11[1]); - result[2] = ilerp_2d(ia, ib, t00[2], t10[2], t01[2], t11[2]); - result[3] = ilerp_2d(ia, ib, t00[3], t10[3], t01[3], t11[3]); -#endif } @@ -191,34 +119,18 @@ lerp_rgba_2d(GLchan result[4], GLfloat a, GLfloat b, * Do trilinear interpolation of colors. */ static INLINE void -lerp_rgba_3d(GLchan result[4], GLfloat a, GLfloat b, GLfloat c, - const GLchan t000[4], const GLchan t100[4], - const GLchan t010[4], const GLchan t110[4], - const GLchan t001[4], const GLchan t101[4], - const GLchan t011[4], const GLchan t111[4]) +lerp_rgba_3d(GLfloat result[4], GLfloat a, GLfloat b, GLfloat c, + const GLfloat t000[4], const GLfloat t100[4], + const GLfloat t010[4], const GLfloat t110[4], + const GLfloat t001[4], const GLfloat t101[4], + const GLfloat t011[4], const GLfloat t111[4]) { GLuint k; /* compiler should unroll these short loops */ -#if CHAN_TYPE == GL_FLOAT for (k = 0; k < 4; k++) { result[k] = lerp_3d(a, b, c, t000[k], t100[k], t010[k], t110[k], t001[k], t101[k], t011[k], t111[k]); } -#elif CHAN_TYPE == GL_UNSIGNED_SHORT - for (k = 0; k < 4; k++) { - result[k] = (GLchan)(lerp_3d(a, b, c, - t000[k], t100[k], t010[k], t110[k], - t001[k], t101[k], t011[k], t111[k]) + 0.5F); - } -#else - GLint ia = IROUND_POS(a * ILERP_SCALE); - GLint ib = IROUND_POS(b * ILERP_SCALE); - GLint ic = IROUND_POS(c * ILERP_SCALE); - for (k = 0; k < 4; k++) { - result[k] = ilerp_3d(ia, ib, ic, t000[k], t100[k], t010[k], t110[k], - t001[k], t101[k], t011[k], t111[k]); - } -#endif } @@ -226,7 +138,7 @@ lerp_rgba_3d(GLchan result[4], GLfloat a, GLfloat b, GLfloat c, * If A is a signed integer, A % B doesn't give the right value for A < 0 * (in terms of texture repeat). Just casting to unsigned fixes that. */ -#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B)) +#define REMAINDER(A, B) (((A) + (B) * 1024) % (B)) /** @@ -502,6 +414,169 @@ linear_repeat_texel_location(GLuint size, GLfloat s, /** + * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode. + */ +static INLINE GLint +clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) +{ + switch (wrapMode) { + case GL_CLAMP: + return IFLOOR( CLAMP(coord, 0.0F, max - 1) ); + case GL_CLAMP_TO_EDGE: + return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) ); + case GL_CLAMP_TO_BORDER: + return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) ); + default: + _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest"); + return 0; + } +} + + +/** + * As above, but GL_LINEAR filtering. + */ +static INLINE void +clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, + GLint *i0out, GLint *i1out, GLfloat *weight) +{ + GLfloat fcol; + GLint i0, i1; + switch (wrapMode) { + case GL_CLAMP: + /* Not exactly what the spec says, but it matches NVIDIA output */ + fcol = CLAMP(coord - 0.5F, 0.0, max-1); + i0 = IFLOOR(fcol); + i1 = i0 + 1; + break; + case GL_CLAMP_TO_EDGE: + fcol = CLAMP(coord, 0.5F, max - 0.5F); + fcol -= 0.5F; + i0 = IFLOOR(fcol); + i1 = i0 + 1; + if (i1 > max - 1) + i1 = max - 1; + break; + case GL_CLAMP_TO_BORDER: + fcol = CLAMP(coord, -0.5F, max + 0.5F); + fcol -= 0.5F; + i0 = IFLOOR(fcol); + i1 = i0 + 1; + break; + default: + _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); + i0 = i1 = 0; + fcol = 0.0F; + } + *i0out = i0; + *i1out = i1; + *weight = FRAC(fcol); +} + + +/** + * Compute nearest integer texcoords for given texobj and coordinate. + */ +static INLINE void +nearest_texcoord(const struct gl_texture_object *texObj, + const GLfloat texcoord[4], + GLint *i, GLint *j, GLint *k) +{ + const GLint baseLevel = texObj->BaseLevel; + const struct gl_texture_image *img = texObj->Image[0][baseLevel]; + const GLint width = img->Width; + const GLint height = img->Height; + const GLint depth = img->Depth; + + switch (texObj->Target) { + case GL_TEXTURE_RECTANGLE_ARB: + *i = clamp_rect_coord_nearest(texObj->WrapS, texcoord[0], width); + *j = clamp_rect_coord_nearest(texObj->WrapT, texcoord[1], height); + *k = 0; + break; + case GL_TEXTURE_1D: + *i = nearest_texel_location(texObj->WrapS, img, width, texcoord[0]); + *j = 0; + *k = 0; + break; + case GL_TEXTURE_2D: + *i = nearest_texel_location(texObj->WrapS, img, width, texcoord[0]); + *j = nearest_texel_location(texObj->WrapT, img, height, texcoord[1]); + *k = 0; + break; + case GL_TEXTURE_1D_ARRAY_EXT: + *i = nearest_texel_location(texObj->WrapS, img, width, texcoord[0]); + *j = clamp_rect_coord_nearest(texObj->WrapT, texcoord[1], height); + *k = 0; + break; + case GL_TEXTURE_2D_ARRAY_EXT: + *i = nearest_texel_location(texObj->WrapS, img, width, texcoord[0]); + *j = nearest_texel_location(texObj->WrapT, img, height, texcoord[1]); + *k = clamp_rect_coord_nearest(texObj->WrapR, texcoord[2], depth); + break; + default: + *i = *j = *k = 0; + } +} + + +/** + * Compute linear integer texcoords for given texobj and coordinate. + */ +static INLINE void +linear_texcoord(const struct gl_texture_object *texObj, + const GLfloat texcoord[4], + GLint *i0, GLint *i1, GLint *j0, GLint *j1, GLint *slice, + GLfloat *wi, GLfloat *wj) +{ + const GLint baseLevel = texObj->BaseLevel; + const struct gl_texture_image *img = texObj->Image[0][baseLevel]; + const GLint width = img->Width; + const GLint height = img->Height; + const GLint depth = img->Depth; + + switch (texObj->Target) { + case GL_TEXTURE_RECTANGLE_ARB: + clamp_rect_coord_linear(texObj->WrapS, texcoord[0], + width, i0, i1, wi); + clamp_rect_coord_linear(texObj->WrapT, texcoord[1], + height, j0, j1, wj); + *slice = 0; + break; + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + linear_texel_locations(texObj->WrapS, img, width, + texcoord[0], i0, i1, wi); + linear_texel_locations(texObj->WrapT, img, height, + texcoord[1], j0, j1, wj); + *slice = 0; + break; + + case GL_TEXTURE_1D_ARRAY_EXT: + linear_texel_locations(texObj->WrapS, img, width, + texcoord[0], i0, i1, wi); + *j0 = clamp_rect_coord_nearest(texObj->WrapT, texcoord[1], height); + *j1 = *j0; + *slice = 0; + break; + + case GL_TEXTURE_2D_ARRAY_EXT: + linear_texel_locations(texObj->WrapS, img, width, + texcoord[0], i0, i1, wi); + linear_texel_locations(texObj->WrapT, img, height, + texcoord[1], j0, j1, wj); + *slice = clamp_rect_coord_nearest(texObj->WrapR, texcoord[2], depth); + break; + + default: + *slice = 0; + } +} + + + +/** * For linear interpolation between mipmap levels N and N+1, this function * computes N. */ @@ -660,6 +735,44 @@ compute_min_mag_ranges(const struct gl_texture_object *tObj, } +/** + * When we sample the border color, it must be interpreted according to + * the base texture format. Ex: if the texture base format it GL_ALPHA, + * we return (0,0,0,BorderAlpha). + */ +static INLINE void +get_border_color(const struct gl_texture_object *tObj, + const struct gl_texture_image *img, + GLfloat rgba[4]) +{ + switch (img->TexFormat->BaseFormat) { + case GL_RGB: + rgba[0] = tObj->BorderColor[0]; + rgba[1] = tObj->BorderColor[1]; + rgba[2] = tObj->BorderColor[2]; + rgba[3] = 1.0F; + break; + case GL_ALPHA: + rgba[0] = rgba[1] = rgba[2] = 0.0; + rgba[3] = tObj->BorderColor[3]; + break; + case GL_LUMINANCE: + rgba[0] = rgba[1] = rgba[2] = tObj->BorderColor[0]; + rgba[3] = 1.0; + break; + case GL_LUMINANCE_ALPHA: + rgba[0] = rgba[1] = rgba[2] = tObj->BorderColor[0]; + rgba[3] = tObj->BorderColor[3]; + break; + case GL_INTENSITY: + rgba[0] = rgba[1] = rgba[2] = rgba[3] = tObj->BorderColor[0]; + break; + default: + COPY_4V(rgba, tObj->BorderColor); + } +} + + /**********************************************************************/ /* 1-D Texture Sampling Functions */ /**********************************************************************/ @@ -671,7 +784,7 @@ static INLINE void sample_1d_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, - const GLfloat texcoord[4], GLchan rgba[4]) + const GLfloat texcoord[4], GLfloat rgba[4]) { const GLint width = img->Width2; /* without border, power of two */ GLint i; @@ -680,10 +793,10 @@ sample_1d_nearest(GLcontext *ctx, i += img->Border; if (i < 0 || i >= (GLint) img->Width) { /* Need this test for GL_CLAMP_TO_BORDER mode */ - COPY_CHAN4(rgba, tObj->_BorderChan); + get_border_color(tObj, img, rgba); } else { - img->FetchTexelc(img, i, 0, 0, rgba); + img->FetchTexelf(img, i, 0, 0, rgba); } } @@ -695,13 +808,13 @@ static INLINE void sample_1d_linear(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, - const GLfloat texcoord[4], GLchan rgba[4]) + const GLfloat texcoord[4], GLfloat rgba[4]) { const GLint width = img->Width2; GLint i0, i1; GLbitfield useBorderColor = 0x0; GLfloat a; - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); @@ -716,16 +829,16 @@ sample_1d_linear(GLcontext *ctx, /* fetch texel colors */ if (useBorderColor & I0BIT) { - COPY_CHAN4(t0, tObj->_BorderChan); + get_border_color(tObj, img, t0); } else { - img->FetchTexelc(img, i0, 0, 0, t0); + img->FetchTexelf(img, i0, 0, 0, t0); } if (useBorderColor & I1BIT) { - COPY_CHAN4(t1, tObj->_BorderChan); + get_border_color(tObj, img, t1); } else { - img->FetchTexelc(img, i1, 0, 0, t1); + img->FetchTexelf(img, i1, 0, 0, t1); } lerp_rgba(rgba, a, t0, t1); @@ -736,7 +849,7 @@ static void sample_1d_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -751,7 +864,7 @@ static void sample_1d_linear_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -766,7 +879,7 @@ static void sample_1d_nearest_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -777,7 +890,7 @@ sample_1d_nearest_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; + GLfloat t0[4], t1[4]; const GLfloat f = FRAC(lambda[i]); sample_1d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_1d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); @@ -791,7 +904,7 @@ static void sample_1d_linear_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -802,7 +915,7 @@ sample_1d_linear_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; + GLfloat t0[4], t1[4]; const GLfloat f = FRAC(lambda[i]); sample_1d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_1d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); @@ -817,7 +930,7 @@ static void sample_nearest_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4] ) + GLfloat rgba[][4] ) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -833,7 +946,7 @@ static void sample_linear_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4] ) + GLfloat rgba[][4] ) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -849,7 +962,7 @@ static void sample_lambda_1d( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4] ) + const GLfloat lambda[], GLfloat rgba[][4] ) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -929,7 +1042,7 @@ sample_2d_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[]) + GLfloat rgba[]) { const GLint width = img->Width2; /* without border, power of two */ const GLint height = img->Height2; /* without border, power of two */ @@ -945,10 +1058,10 @@ sample_2d_nearest(GLcontext *ctx, if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) { /* Need this test for GL_CLAMP_TO_BORDER mode */ - COPY_CHAN4(rgba, tObj->_BorderChan); + get_border_color(tObj, img, rgba); } else { - img->FetchTexelc(img, i, j, 0, rgba); + img->FetchTexelf(img, i, j, 0, rgba); } } @@ -962,14 +1075,14 @@ sample_2d_linear(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[]) + GLfloat rgba[]) { const GLint width = img->Width2; const GLint height = img->Height2; GLint i0, j0, i1, j1; GLbitfield useBorderColor = 0x0; GLfloat a, b; - GLchan t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ + GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); @@ -989,28 +1102,28 @@ sample_2d_linear(GLcontext *ctx, /* fetch four texel colors */ if (useBorderColor & (I0BIT | J0BIT)) { - COPY_CHAN4(t00, tObj->_BorderChan); + get_border_color(tObj, img, t00); } else { - img->FetchTexelc(img, i0, j0, 0, t00); + img->FetchTexelf(img, i0, j0, 0, t00); } if (useBorderColor & (I1BIT | J0BIT)) { - COPY_CHAN4(t10, tObj->_BorderChan); + get_border_color(tObj, img, t10); } else { - img->FetchTexelc(img, i1, j0, 0, t10); + img->FetchTexelf(img, i1, j0, 0, t10); } if (useBorderColor & (I0BIT | J1BIT)) { - COPY_CHAN4(t01, tObj->_BorderChan); + get_border_color(tObj, img, t01); } else { - img->FetchTexelc(img, i0, j1, 0, t01); + img->FetchTexelf(img, i0, j1, 0, t01); } if (useBorderColor & (I1BIT | J1BIT)) { - COPY_CHAN4(t11, tObj->_BorderChan); + get_border_color(tObj, img, t11); } else { - img->FetchTexelc(img, i1, j1, 0, t11); + img->FetchTexelf(img, i1, j1, 0, t11); } lerp_rgba_2d(rgba, a, b, t00, t10, t01, t11); @@ -1026,13 +1139,13 @@ sample_2d_linear_repeat(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[]) + GLfloat rgba[]) { const GLint width = img->Width2; const GLint height = img->Height2; GLint i0, j0, i1, j1; GLfloat wi, wj; - GLchan t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ + GLfloat t00[4], t10[4], t01[4], t11[4]; /* sampled texel colors */ (void) ctx; @@ -1045,10 +1158,10 @@ sample_2d_linear_repeat(GLcontext *ctx, linear_repeat_texel_location(width, texcoord[0], &i0, &i1, &wi); linear_repeat_texel_location(height, texcoord[1], &j0, &j1, &wj); - img->FetchTexelc(img, i0, j0, 0, t00); - img->FetchTexelc(img, i1, j0, 0, t10); - img->FetchTexelc(img, i0, j1, 0, t01); - img->FetchTexelc(img, i1, j1, 0, t11); + img->FetchTexelf(img, i0, j0, 0, t00); + img->FetchTexelf(img, i1, j0, 0, t10); + img->FetchTexelf(img, i0, j1, 0, t01); + img->FetchTexelf(img, i1, j1, 0, t11); lerp_rgba_2d(rgba, wi, wj, t00, t10, t01, t11); } @@ -1058,7 +1171,7 @@ static void sample_2d_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; for (i = 0; i < n; i++) { @@ -1072,7 +1185,7 @@ static void sample_2d_linear_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1087,7 +1200,7 @@ static void sample_2d_nearest_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1098,7 +1211,7 @@ sample_2d_nearest_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_2d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_2d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); @@ -1112,7 +1225,7 @@ static void sample_2d_linear_mipmap_linear( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4] ) + const GLfloat lambda[], GLfloat rgba[][4] ) { GLuint i; ASSERT(lambda != NULL); @@ -1123,7 +1236,7 @@ sample_2d_linear_mipmap_linear( GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_2d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_2d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); @@ -1137,7 +1250,7 @@ static void sample_2d_linear_mipmap_linear_repeat(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1150,7 +1263,7 @@ sample_2d_linear_mipmap_linear_repeat(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_2d_linear_repeat(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); @@ -1167,7 +1280,7 @@ static void sample_nearest_2d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -1183,7 +1296,7 @@ static void sample_linear_2d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -1216,7 +1329,7 @@ static void opt_sample_rgb_2d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; const GLfloat width = (GLfloat) img->Width; @@ -1238,9 +1351,9 @@ opt_sample_rgb_2d(GLcontext *ctx, GLint j = IFLOOR(texcoords[k][1] * height) & rowMask; GLint pos = (j << shift) | i; GLchan *texel = ((GLchan *) img->Data) + 3*pos; - rgba[k][RCOMP] = texel[0]; - rgba[k][GCOMP] = texel[1]; - rgba[k][BCOMP] = texel[2]; + rgba[k][RCOMP] = CHAN_TO_FLOAT(texel[0]); + rgba[k][GCOMP] = CHAN_TO_FLOAT(texel[1]); + rgba[k][BCOMP] = CHAN_TO_FLOAT(texel[2]); } } @@ -1257,7 +1370,7 @@ static void opt_sample_rgba_2d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][tObj->BaseLevel]; const GLfloat width = (GLfloat) img->Width; @@ -1279,7 +1392,10 @@ opt_sample_rgba_2d(GLcontext *ctx, const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask; const GLint pos = (row << shift) | col; const GLchan *texel = ((GLchan *) img->Data) + (pos << 2); /* pos*4 */ - COPY_CHAN4(rgba[i], texel); + rgba[i][RCOMP] = CHAN_TO_FLOAT(texel[0]); + rgba[i][GCOMP] = CHAN_TO_FLOAT(texel[1]); + rgba[i][BCOMP] = CHAN_TO_FLOAT(texel[2]); + rgba[i][ACOMP] = CHAN_TO_FLOAT(texel[3]); } } @@ -1289,7 +1405,7 @@ static void sample_lambda_2d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { const struct gl_texture_image *tImg = tObj->Image[0][tObj->BaseLevel]; GLuint minStart, minEnd; /* texels with minification */ @@ -1411,7 +1527,7 @@ sample_3d_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[4]) + GLfloat rgba[4]) { const GLint width = img->Width2; /* without border, power of two */ const GLint height = img->Height2; /* without border, power of two */ @@ -1427,10 +1543,10 @@ sample_3d_nearest(GLcontext *ctx, j < 0 || j >= (GLint) img->Height || k < 0 || k >= (GLint) img->Depth) { /* Need this test for GL_CLAMP_TO_BORDER mode */ - COPY_CHAN4(rgba, tObj->_BorderChan); + get_border_color(tObj, img, rgba); } else { - img->FetchTexelc(img, i, j, k, rgba); + img->FetchTexelf(img, i, j, k, rgba); } } @@ -1443,7 +1559,7 @@ sample_3d_linear(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[4]) + GLfloat rgba[4]) { const GLint width = img->Width2; const GLint height = img->Height2; @@ -1451,8 +1567,8 @@ sample_3d_linear(GLcontext *ctx, GLint i0, j0, k0, i1, j1, k1; GLbitfield useBorderColor = 0x0; GLfloat a, b, c; - GLchan t000[4], t010[4], t001[4], t011[4]; - GLchan t100[4], t110[4], t101[4], t111[4]; + GLfloat t000[4], t010[4], t001[4], t011[4]; + GLfloat t100[4], t110[4], t101[4], t111[4]; linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); @@ -1478,53 +1594,53 @@ sample_3d_linear(GLcontext *ctx, /* Fetch texels */ if (useBorderColor & (I0BIT | J0BIT | K0BIT)) { - COPY_CHAN4(t000, tObj->_BorderChan); + get_border_color(tObj, img, t000); } else { - img->FetchTexelc(img, i0, j0, k0, t000); + img->FetchTexelf(img, i0, j0, k0, t000); } if (useBorderColor & (I1BIT | J0BIT | K0BIT)) { - COPY_CHAN4(t100, tObj->_BorderChan); + get_border_color(tObj, img, t100); } else { - img->FetchTexelc(img, i1, j0, k0, t100); + img->FetchTexelf(img, i1, j0, k0, t100); } if (useBorderColor & (I0BIT | J1BIT | K0BIT)) { - COPY_CHAN4(t010, tObj->_BorderChan); + get_border_color(tObj, img, t010); } else { - img->FetchTexelc(img, i0, j1, k0, t010); + img->FetchTexelf(img, i0, j1, k0, t010); } if (useBorderColor & (I1BIT | J1BIT | K0BIT)) { - COPY_CHAN4(t110, tObj->_BorderChan); + get_border_color(tObj, img, t110); } else { - img->FetchTexelc(img, i1, j1, k0, t110); + img->FetchTexelf(img, i1, j1, k0, t110); } if (useBorderColor & (I0BIT | J0BIT | K1BIT)) { - COPY_CHAN4(t001, tObj->_BorderChan); + get_border_color(tObj, img, t001); } else { - img->FetchTexelc(img, i0, j0, k1, t001); + img->FetchTexelf(img, i0, j0, k1, t001); } if (useBorderColor & (I1BIT | J0BIT | K1BIT)) { - COPY_CHAN4(t101, tObj->_BorderChan); + get_border_color(tObj, img, t101); } else { - img->FetchTexelc(img, i1, j0, k1, t101); + img->FetchTexelf(img, i1, j0, k1, t101); } if (useBorderColor & (I0BIT | J1BIT | K1BIT)) { - COPY_CHAN4(t011, tObj->_BorderChan); + get_border_color(tObj, img, t011); } else { - img->FetchTexelc(img, i0, j1, k1, t011); + img->FetchTexelf(img, i0, j1, k1, t011); } if (useBorderColor & (I1BIT | J1BIT | K1BIT)) { - COPY_CHAN4(t111, tObj->_BorderChan); + get_border_color(tObj, img, t111); } else { - img->FetchTexelc(img, i1, j1, k1, t111); + img->FetchTexelf(img, i1, j1, k1, t111); } /* trilinear interpolation of samples */ @@ -1536,7 +1652,7 @@ static void sample_3d_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4] ) + const GLfloat lambda[], GLfloat rgba[][4] ) { GLuint i; for (i = 0; i < n; i++) { @@ -1550,7 +1666,7 @@ static void sample_3d_linear_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1565,7 +1681,7 @@ static void sample_3d_nearest_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1576,7 +1692,7 @@ sample_3d_nearest_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_3d_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_3d_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); @@ -1590,7 +1706,7 @@ static void sample_3d_linear_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1601,7 +1717,7 @@ sample_3d_linear_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_3d_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_3d_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); @@ -1616,7 +1732,7 @@ static void sample_nearest_3d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -1632,7 +1748,7 @@ static void sample_linear_3d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -1648,7 +1764,7 @@ static void sample_lambda_3d(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -1799,7 +1915,7 @@ static void sample_nearest_cube(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint i; (void) lambda; @@ -1817,7 +1933,7 @@ static void sample_linear_cube(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; (void) lambda; @@ -1835,7 +1951,7 @@ static void sample_cube_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1864,7 +1980,7 @@ static void sample_cube_linear_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1883,7 +1999,7 @@ static void sample_cube_nearest_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1898,7 +2014,7 @@ sample_cube_nearest_mipmap_linear(GLcontext *ctx, newCoord, rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_2d_nearest(ctx, tObj, images[level ], newCoord, t0); sample_2d_nearest(ctx, tObj, images[level+1], newCoord, t1); @@ -1912,7 +2028,7 @@ static void sample_cube_linear_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -1927,7 +2043,7 @@ sample_cube_linear_mipmap_linear(GLcontext *ctx, newCoord, rgba[i]); } else { - GLchan t0[4], t1[4]; + GLfloat t0[4], t1[4]; const GLfloat f = FRAC(lambda[i]); sample_2d_linear(ctx, tObj, images[level ], newCoord, t0); sample_2d_linear(ctx, tObj, images[level+1], newCoord, t1); @@ -1942,7 +2058,7 @@ static void sample_lambda_cube(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -2012,71 +2128,11 @@ sample_lambda_cube(GLcontext *ctx, /**********************************************************************/ -/** - * Do clamp/wrap for a texture rectangle coord, GL_NEAREST filter mode. - */ -static INLINE GLint -clamp_rect_coord_nearest(GLenum wrapMode, GLfloat coord, GLint max) -{ - switch (wrapMode) { - case GL_CLAMP: - return IFLOOR( CLAMP(coord, 0.0F, max - 1) ); - case GL_CLAMP_TO_EDGE: - return IFLOOR( CLAMP(coord, 0.5F, max - 0.5F) ); - case GL_CLAMP_TO_BORDER: - return IFLOOR( CLAMP(coord, -0.5F, max + 0.5F) ); - default: - _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_nearest"); - return 0; - } -} - - -/** - * As above, but GL_LINEAR filtering. - */ -static INLINE void -clamp_rect_coord_linear(GLenum wrapMode, GLfloat coord, GLint max, - GLint *i0out, GLint *i1out, GLfloat *weight) -{ - GLfloat fcol; - GLint i0, i1; - switch (wrapMode) { - case GL_CLAMP: - /* Not exactly what the spec says, but it matches NVIDIA output */ - fcol = CLAMP(coord - 0.5F, 0.0, max-1); - i0 = IFLOOR(fcol); - i1 = i0 + 1; - break; - case GL_CLAMP_TO_EDGE: - fcol = CLAMP(coord, 0.5F, max - 0.5F); - fcol -= 0.5F; - i0 = IFLOOR(fcol); - i1 = i0 + 1; - if (i1 > max - 1) - i1 = max - 1; - break; - case GL_CLAMP_TO_BORDER: - fcol = CLAMP(coord, -0.5F, max + 0.5F); - fcol -= 0.5F; - i0 = IFLOOR(fcol); - i1 = i0 + 1; - default: - _mesa_problem(NULL, "bad wrapMode in clamp_rect_coord_linear"); - i0 = i1 = 0; - fcol = 0.0F; - } - *i0out = i0; - *i1out = i1; - *weight = FRAC(fcol); -} - - static void sample_nearest_rect(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][0]; const GLint width = img->Width; @@ -2099,9 +2155,9 @@ sample_nearest_rect(GLcontext *ctx, col = clamp_rect_coord_nearest(tObj->WrapS, texcoords[i][0], width); row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); if (col < 0 || col >= width || row < 0 || row >= height) - COPY_CHAN4(rgba[i], tObj->_BorderChan); + get_border_color(tObj, img, rgba[i]); else - img->FetchTexelc(img, col, row, 0, rgba[i]); + img->FetchTexelf(img, col, row, 0, rgba[i]); } } @@ -2110,7 +2166,7 @@ static void sample_linear_rect(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { const struct gl_texture_image *img = tObj->Image[0][0]; const GLint width = img->Width; @@ -2130,7 +2186,7 @@ sample_linear_rect(GLcontext *ctx, for (i = 0; i < n; i++) { GLint i0, j0, i1, j1; - GLchan t00[4], t01[4], t10[4], t11[4]; + GLfloat t00[4], t01[4], t10[4], t11[4]; GLfloat a, b; GLbitfield useBorderColor = 0x0; @@ -2147,24 +2203,24 @@ sample_linear_rect(GLcontext *ctx, /* get four texel samples */ if (useBorderColor & (I0BIT | J0BIT)) - COPY_CHAN4(t00, tObj->_BorderChan); + get_border_color(tObj, img, t00); else - img->FetchTexelc(img, i0, j0, 0, t00); + img->FetchTexelf(img, i0, j0, 0, t00); if (useBorderColor & (I1BIT | J0BIT)) - COPY_CHAN4(t10, tObj->_BorderChan); + get_border_color(tObj, img, t10); else - img->FetchTexelc(img, i1, j0, 0, t10); + img->FetchTexelf(img, i1, j0, 0, t10); if (useBorderColor & (I0BIT | J1BIT)) - COPY_CHAN4(t01, tObj->_BorderChan); + get_border_color(tObj, img, t01); else - img->FetchTexelc(img, i0, j1, 0, t01); + img->FetchTexelf(img, i0, j1, 0, t01); if (useBorderColor & (I1BIT | J1BIT)) - COPY_CHAN4(t11, tObj->_BorderChan); + get_border_color(tObj, img, t11); else - img->FetchTexelc(img, i1, j1, 0, t11); + img->FetchTexelf(img, i1, j1, 0, t11); lerp_rgba_2d(rgba[i], a, b, t00, t10, t01, t11); } @@ -2176,7 +2232,7 @@ static void sample_lambda_rect(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint minStart, minEnd, magStart, magEnd; @@ -2222,7 +2278,7 @@ sample_2d_array_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[4]) + GLfloat rgba[4]) { const GLint width = img->Width2; /* without border, power of two */ const GLint height = img->Height2; /* without border, power of two */ @@ -2239,10 +2295,10 @@ sample_2d_array_nearest(GLcontext *ctx, j < 0 || j >= (GLint) img->Height || array < 0 || array >= (GLint) img->Depth) { /* Need this test for GL_CLAMP_TO_BORDER mode */ - COPY_CHAN4(rgba, tObj->_BorderChan); + get_border_color(tObj, img, rgba); } else { - img->FetchTexelc(img, i, j, array, rgba); + img->FetchTexelf(img, i, j, array, rgba); } } @@ -2255,7 +2311,7 @@ sample_2d_array_linear(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[4]) + GLfloat rgba[4]) { const GLint width = img->Width2; const GLint height = img->Height2; @@ -2264,14 +2320,14 @@ sample_2d_array_linear(GLcontext *ctx, GLint array; GLbitfield useBorderColor = 0x0; GLfloat a, b; - GLchan t00[4], t01[4], t10[4], t11[4]; + GLfloat t00[4], t01[4], t10[4], t11[4]; linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); linear_texel_locations(tObj->WrapT, img, height, texcoord[1], &j0, &j1, &b); array = clamp_rect_coord_nearest(tObj->WrapR, texcoord[2], depth); if (array < 0 || array >= depth) { - COPY_CHAN4(rgba, tObj->_BorderChan); + COPY_4V(rgba, tObj->BorderColor); } else { if (img->Border) { @@ -2290,28 +2346,28 @@ sample_2d_array_linear(GLcontext *ctx, /* Fetch texels */ if (useBorderColor & (I0BIT | J0BIT)) { - COPY_CHAN4(t00, tObj->_BorderChan); + get_border_color(tObj, img, t00); } else { - img->FetchTexelc(img, i0, j0, array, t00); + img->FetchTexelf(img, i0, j0, array, t00); } if (useBorderColor & (I1BIT | J0BIT)) { - COPY_CHAN4(t10, tObj->_BorderChan); + get_border_color(tObj, img, t10); } else { - img->FetchTexelc(img, i1, j0, array, t10); + img->FetchTexelf(img, i1, j0, array, t10); } if (useBorderColor & (I0BIT | J1BIT)) { - COPY_CHAN4(t01, tObj->_BorderChan); + get_border_color(tObj, img, t01); } else { - img->FetchTexelc(img, i0, j1, array, t01); + img->FetchTexelf(img, i0, j1, array, t01); } if (useBorderColor & (I1BIT | J1BIT)) { - COPY_CHAN4(t11, tObj->_BorderChan); + get_border_color(tObj, img, t11); } else { - img->FetchTexelc(img, i1, j1, array, t11); + img->FetchTexelf(img, i1, j1, array, t11); } /* trilinear interpolation of samples */ @@ -2324,7 +2380,7 @@ static void sample_2d_array_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; for (i = 0; i < n; i++) { @@ -2339,7 +2395,7 @@ static void sample_2d_array_linear_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2355,7 +2411,7 @@ static void sample_2d_array_nearest_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2366,7 +2422,7 @@ sample_2d_array_nearest_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_2d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); @@ -2382,7 +2438,7 @@ static void sample_2d_array_linear_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2393,7 +2449,7 @@ sample_2d_array_linear_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_2d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); @@ -2410,7 +2466,7 @@ static void sample_nearest_2d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -2427,7 +2483,7 @@ static void sample_linear_2d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -2443,7 +2499,7 @@ static void sample_lambda_2d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -2532,7 +2588,7 @@ sample_1d_array_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[4]) + GLfloat rgba[4]) { const GLint width = img->Width2; /* without border, power of two */ const GLint height = img->Height; @@ -2546,10 +2602,10 @@ sample_1d_array_nearest(GLcontext *ctx, if (i < 0 || i >= (GLint) img->Width || array < 0 || array >= (GLint) img->Height) { /* Need this test for GL_CLAMP_TO_BORDER mode */ - COPY_CHAN4(rgba, tObj->_BorderChan); + get_border_color(tObj, img, rgba); } else { - img->FetchTexelc(img, i, array, 0, rgba); + img->FetchTexelf(img, i, array, 0, rgba); } } @@ -2562,7 +2618,7 @@ sample_1d_array_linear(GLcontext *ctx, const struct gl_texture_object *tObj, const struct gl_texture_image *img, const GLfloat texcoord[4], - GLchan rgba[4]) + GLfloat rgba[4]) { const GLint width = img->Width2; const GLint height = img->Height; @@ -2570,7 +2626,7 @@ sample_1d_array_linear(GLcontext *ctx, GLint array; GLbitfield useBorderColor = 0x0; GLfloat a; - GLchan t0[4], t1[4]; + GLfloat t0[4], t1[4]; linear_texel_locations(tObj->WrapS, img, width, texcoord[0], &i0, &i1, &a); array = clamp_rect_coord_nearest(tObj->WrapT, texcoord[1], height); @@ -2589,16 +2645,16 @@ sample_1d_array_linear(GLcontext *ctx, /* Fetch texels */ if (useBorderColor & (I0BIT | K0BIT)) { - COPY_CHAN4(t0, tObj->_BorderChan); + get_border_color(tObj, img, t0); } else { - img->FetchTexelc(img, i0, array, 0, t0); + img->FetchTexelf(img, i0, array, 0, t0); } if (useBorderColor & (I1BIT | K0BIT)) { - COPY_CHAN4(t1, tObj->_BorderChan); + get_border_color(tObj, img, t1); } else { - img->FetchTexelc(img, i1, array, 0, t1); + img->FetchTexelf(img, i1, array, 0, t1); } /* bilinear interpolation of samples */ @@ -2610,7 +2666,7 @@ static void sample_1d_array_nearest_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; for (i = 0; i < n; i++) { @@ -2625,7 +2681,7 @@ static void sample_1d_array_linear_mipmap_nearest(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2641,7 +2697,7 @@ static void sample_1d_array_nearest_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2652,7 +2708,7 @@ sample_1d_array_nearest_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_1d_array_nearest(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); @@ -2666,7 +2722,7 @@ static void sample_1d_array_linear_mipmap_linear(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoord[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; ASSERT(lambda != NULL); @@ -2677,7 +2733,7 @@ sample_1d_array_linear_mipmap_linear(GLcontext *ctx, texcoord[i], rgba[i]); } else { - GLchan t0[4], t1[4]; /* texels */ + GLfloat t0[4], t1[4]; /* texels */ const GLfloat f = FRAC(lambda[i]); sample_1d_array_linear(ctx, tObj, tObj->Image[0][level ], texcoord[i], t0); sample_1d_array_linear(ctx, tObj, tObj->Image[0][level+1], texcoord[i], t1); @@ -2692,7 +2748,7 @@ static void sample_nearest_1d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -2708,7 +2764,7 @@ static void sample_linear_1d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], - const GLfloat lambda[], GLchan rgba[][4]) + const GLfloat lambda[], GLfloat rgba[][4]) { GLuint i; struct gl_texture_image *image = tObj->Image[0][tObj->BaseLevel]; @@ -2724,7 +2780,7 @@ static void sample_lambda_1d_array(GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint minStart, minEnd; /* texels with minification */ GLuint magStart, magEnd; /* texels with magnification */ @@ -2796,13 +2852,109 @@ sample_lambda_1d_array(GLcontext *ctx, /** + * Compare texcoord against depth sample. Return 1.0 or the ambient value. + */ +static INLINE GLfloat +shadow_compare(GLenum function, GLfloat coord, GLfloat depthSample, + GLfloat ambient) +{ + switch (function) { + case GL_LEQUAL: + return (coord <= depthSample) ? 1.0F : ambient; + case GL_GEQUAL: + return (coord >= depthSample) ? 1.0F : ambient; + case GL_LESS: + return (coord < depthSample) ? 1.0F : ambient; + case GL_GREATER: + return (coord > depthSample) ? 1.0F : ambient; + case GL_EQUAL: + return (coord == depthSample) ? 1.0F : ambient; + case GL_NOTEQUAL: + return (coord != depthSample) ? 1.0F : ambient; + case GL_ALWAYS: + return 1.0F; + case GL_NEVER: + return ambient; + case GL_NONE: + return depthSample; + default: + _mesa_problem(NULL, "Bad compare func in shadow_compare"); + return ambient; + } +} + + +/** + * Compare texcoord against four depth samples. + */ +static INLINE GLfloat +shadow_compare4(GLenum function, GLfloat coord, + GLfloat depth00, GLfloat depth01, + GLfloat depth10, GLfloat depth11, + GLfloat ambient, GLfloat wi, GLfloat wj) +{ + const GLfloat d = (1.0F - (GLfloat) ambient) * 0.25F; + GLfloat luminance = 1.0F; + + switch (function) { + case GL_LEQUAL: + if (depth00 <= coord) luminance -= d; + if (depth01 <= coord) luminance -= d; + if (depth10 <= coord) luminance -= d; + if (depth11 <= coord) luminance -= d; + return luminance; + case GL_GEQUAL: + if (depth00 >= coord) luminance -= d; + if (depth01 >= coord) luminance -= d; + if (depth10 >= coord) luminance -= d; + if (depth11 >= coord) luminance -= d; + return luminance; + case GL_LESS: + if (depth00 < coord) luminance -= d; + if (depth01 < coord) luminance -= d; + if (depth10 < coord) luminance -= d; + if (depth11 < coord) luminance -= d; + return luminance; + case GL_GREATER: + if (depth00 > coord) luminance -= d; + if (depth01 > coord) luminance -= d; + if (depth10 > coord) luminance -= d; + if (depth11 > coord) luminance -= d; + return luminance; + case GL_EQUAL: + if (depth00 == coord) luminance -= d; + if (depth01 == coord) luminance -= d; + if (depth10 == coord) luminance -= d; + if (depth11 == coord) luminance -= d; + return luminance; + case GL_NOTEQUAL: + if (depth00 != coord) luminance -= d; + if (depth01 != coord) luminance -= d; + if (depth10 != coord) luminance -= d; + if (depth11 != coord) luminance -= d; + return luminance; + case GL_ALWAYS: + return 0.0; + case GL_NEVER: + return ambient; + case GL_NONE: + /* ordinary bilinear filtering */ + return lerp_2d(wi, wj, depth00, depth10, depth01, depth11); + default: + _mesa_problem(NULL, "Bad compare func in sample_depth_texture"); + return 0.0F; + } +} + + +/** * Sample a shadow/depth texture. */ static void sample_depth_texture( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan texel[][4] ) + GLfloat texel[][4] ) { const GLint baseLevel = tObj->BaseLevel; const struct gl_texture_image *img = tObj->Image[0][baseLevel]; @@ -2811,9 +2963,9 @@ sample_depth_texture( GLcontext *ctx, const GLint depth = img->Depth; const GLuint compare_coord = (tObj->Target == GL_TEXTURE_2D_ARRAY_EXT) ? 3 : 2; - GLchan ambient; + GLfloat ambient; GLenum function; - GLchan result; + GLfloat result; (void) lambda; @@ -2826,56 +2978,20 @@ sample_depth_texture( GLcontext *ctx, tObj->Target == GL_TEXTURE_1D_ARRAY_EXT || tObj->Target == GL_TEXTURE_2D_ARRAY_EXT); - UNCLAMPED_FLOAT_TO_CHAN(ambient, tObj->ShadowAmbient); + ambient = tObj->CompareFailValue; /* XXXX if tObj->MinFilter != tObj->MagFilter, we're ignoring lambda */ - function = tObj->_Function; + function = (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) ? + tObj->CompareFunc : GL_NONE; + if (tObj->MagFilter == GL_NEAREST) { GLuint i; for (i = 0; i < n; i++) { GLfloat depthSample; GLint col, row, slice; - switch (tObj->Target) { - case GL_TEXTURE_RECTANGLE_ARB: - col = clamp_rect_coord_nearest(tObj->WrapS, texcoords[i][0], width); - row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); - slice = 0; - break; - - case GL_TEXTURE_1D: - col = nearest_texel_location(tObj->WrapS, img, width, - texcoords[i][0]); - row = 0; - slice = 0; - break; - - case GL_TEXTURE_2D: - col = nearest_texel_location(tObj->WrapS, img, width, - texcoords[i][0]); - row = nearest_texel_location(tObj->WrapT, img, height, - texcoords[i][1]); - slice = 0; - break; - - case GL_TEXTURE_1D_ARRAY_EXT: - col = nearest_texel_location(tObj->WrapS, img, width, - texcoords[i][0]); - row = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); - slice = 0; - break; - - case GL_TEXTURE_2D_ARRAY_EXT: - col = nearest_texel_location(tObj->WrapS, img, width, - texcoords[i][0]); - row = nearest_texel_location(tObj->WrapT, img, height, - texcoords[i][1]); - slice = clamp_rect_coord_nearest(tObj->WrapR, texcoords[i][2], depth); - break; - default: - col = row = slice = 0; - } + nearest_texcoord(tObj, texcoords[i], &col, &row, &slice); if (col >= 0 && row >= 0 && col < width && row < height && slice >= 0 && slice < depth) { @@ -2885,57 +3001,18 @@ sample_depth_texture( GLcontext *ctx, depthSample = tObj->BorderColor[0]; } - switch (function) { - case GL_LEQUAL: - result = (texcoords[i][compare_coord] <= depthSample) ? CHAN_MAX : ambient; - break; - case GL_GEQUAL: - result = (texcoords[i][compare_coord] >= depthSample) ? CHAN_MAX : ambient; - break; - case GL_LESS: - result = (texcoords[i][compare_coord] < depthSample) ? CHAN_MAX : ambient; - break; - case GL_GREATER: - result = (texcoords[i][compare_coord] > depthSample) ? CHAN_MAX : ambient; - break; - case GL_EQUAL: - result = (texcoords[i][compare_coord] == depthSample) ? CHAN_MAX : ambient; - break; - case GL_NOTEQUAL: - result = (texcoords[i][compare_coord] != depthSample) ? CHAN_MAX : ambient; - break; - case GL_ALWAYS: - result = CHAN_MAX; - break; - case GL_NEVER: - result = ambient; - break; - case GL_NONE: - CLAMPED_FLOAT_TO_CHAN(result, depthSample); - break; - default: - _mesa_problem(ctx, "Bad compare func in sample_depth_texture"); - return; - } + result = shadow_compare(function, texcoords[i][compare_coord], + depthSample, ambient); switch (tObj->DepthMode) { case GL_LUMINANCE: - texel[i][RCOMP] = result; - texel[i][GCOMP] = result; - texel[i][BCOMP] = result; - texel[i][ACOMP] = CHAN_MAX; + ASSIGN_4V(texel[i], result, result, result, 1.0F); break; case GL_INTENSITY: - texel[i][RCOMP] = result; - texel[i][GCOMP] = result; - texel[i][BCOMP] = result; - texel[i][ACOMP] = result; + ASSIGN_4V(texel[i], result, result, result, result); break; case GL_ALPHA: - texel[i][RCOMP] = 0; - texel[i][GCOMP] = 0; - texel[i][BCOMP] = 0; - texel[i][ACOMP] = result; + ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result); break; default: _mesa_problem(ctx, "Bad depth texture mode"); @@ -2949,45 +3026,11 @@ sample_depth_texture( GLcontext *ctx, GLfloat depth00, depth01, depth10, depth11; GLint i0, i1, j0, j1; GLint slice; - GLfloat a, b; + GLfloat wi, wj; GLuint useBorderTexel; - switch (tObj->Target) { - case GL_TEXTURE_RECTANGLE_ARB: - clamp_rect_coord_linear(tObj->WrapS, texcoords[i][0], - width, &i0, &i1, &a); - clamp_rect_coord_linear(tObj->WrapT, texcoords[i][1], - height, &j0, &j1, &b); - slice = 0; - break; - - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - linear_texel_locations(tObj->WrapS, img, width, - texcoords[i][0], &i0, &i1, &a); - linear_texel_locations(tObj->WrapT, img, height, - texcoords[i][1], &j0, &j1, &b); - slice = 0; - break; - - case GL_TEXTURE_1D_ARRAY_EXT: - linear_texel_locations(tObj->WrapS, img, width, - texcoords[i][0], &i0, &i1, &a); - j0 = clamp_rect_coord_nearest(tObj->WrapT, texcoords[i][1], height); - j1 = j0; - slice = 0; - break; - - case GL_TEXTURE_2D_ARRAY_EXT: - linear_texel_locations(tObj->WrapS, img, width, - texcoords[i][0], &i0, &i1, &a); - linear_texel_locations(tObj->WrapT, img, height, - texcoords[i][1], &j0, &j1, &b); - slice = clamp_rect_coord_nearest(tObj->WrapR, texcoords[i][2], depth); - break; - default: - slice = 0; - } + linear_texcoord(tObj, texcoords[i], &i0, &i1, &j0, &j1, &slice, + &wi, &wj); useBorderTexel = 0; if (img->Border) { @@ -3046,213 +3089,29 @@ sample_depth_texture( GLcontext *ctx, } } - if (0) { - /* compute a single weighted depth sample and do one comparison */ - const GLfloat depthSample - = lerp_2d(a, b, depth00, depth10, depth01, depth11); - if ((depthSample <= texcoords[i][compare_coord] && function == GL_LEQUAL) || - (depthSample >= texcoords[i][compare_coord] && function == GL_GEQUAL)) { - result = ambient; - } - else { - result = CHAN_MAX; - } - } - else { - /* Do four depth/R comparisons and compute a weighted result. - * If this touches on somebody's I.P., I'll remove this code - * upon request. - */ - const GLfloat d = (CHAN_MAXF - (GLfloat) ambient) * 0.25F; - GLfloat luminance = CHAN_MAXF; - - switch (function) { - case GL_LEQUAL: - if (depth00 <= texcoords[i][compare_coord]) luminance -= d; - if (depth01 <= texcoords[i][compare_coord]) luminance -= d; - if (depth10 <= texcoords[i][compare_coord]) luminance -= d; - if (depth11 <= texcoords[i][compare_coord]) luminance -= d; - result = (GLchan) luminance; - break; - case GL_GEQUAL: - if (depth00 >= texcoords[i][compare_coord]) luminance -= d; - if (depth01 >= texcoords[i][compare_coord]) luminance -= d; - if (depth10 >= texcoords[i][compare_coord]) luminance -= d; - if (depth11 >= texcoords[i][compare_coord]) luminance -= d; - result = (GLchan) luminance; - break; - case GL_LESS: - if (depth00 < texcoords[i][compare_coord]) luminance -= d; - if (depth01 < texcoords[i][compare_coord]) luminance -= d; - if (depth10 < texcoords[i][compare_coord]) luminance -= d; - if (depth11 < texcoords[i][compare_coord]) luminance -= d; - result = (GLchan) luminance; - break; - case GL_GREATER: - if (depth00 > texcoords[i][compare_coord]) luminance -= d; - if (depth01 > texcoords[i][compare_coord]) luminance -= d; - if (depth10 > texcoords[i][compare_coord]) luminance -= d; - if (depth11 > texcoords[i][compare_coord]) luminance -= d; - result = (GLchan) luminance; - break; - case GL_EQUAL: - if (depth00 == texcoords[i][compare_coord]) luminance -= d; - if (depth01 == texcoords[i][compare_coord]) luminance -= d; - if (depth10 == texcoords[i][compare_coord]) luminance -= d; - if (depth11 == texcoords[i][compare_coord]) luminance -= d; - result = (GLchan) luminance; - break; - case GL_NOTEQUAL: - if (depth00 != texcoords[i][compare_coord]) luminance -= d; - if (depth01 != texcoords[i][compare_coord]) luminance -= d; - if (depth10 != texcoords[i][compare_coord]) luminance -= d; - if (depth11 != texcoords[i][compare_coord]) luminance -= d; - result = (GLchan) luminance; - break; - case GL_ALWAYS: - result = 0; - break; - case GL_NEVER: - result = CHAN_MAX; - break; - case GL_NONE: - /* ordinary bilinear filtering */ - { - const GLfloat depthSample - = lerp_2d(a, b, depth00, depth10, depth01, depth11); - CLAMPED_FLOAT_TO_CHAN(result, depthSample); - } - break; - default: - _mesa_problem(ctx, "Bad compare func in sample_depth_texture"); - return; - } - } + result = shadow_compare4(function, texcoords[i][compare_coord], + depth00, depth01, depth10, depth11, + ambient, wi, wj); switch (tObj->DepthMode) { case GL_LUMINANCE: - texel[i][RCOMP] = result; - texel[i][GCOMP] = result; - texel[i][BCOMP] = result; - texel[i][ACOMP] = CHAN_MAX; + ASSIGN_4V(texel[i], result, result, result, 1.0F); break; case GL_INTENSITY: - texel[i][RCOMP] = result; - texel[i][GCOMP] = result; - texel[i][BCOMP] = result; - texel[i][ACOMP] = result; + ASSIGN_4V(texel[i], result, result, result, result); break; case GL_ALPHA: - texel[i][RCOMP] = 0; - texel[i][GCOMP] = 0; - texel[i][BCOMP] = 0; - texel[i][ACOMP] = result; + ASSIGN_4V(texel[i], 0.0F, 0.0F, 0.0F, result); break; default: _mesa_problem(ctx, "Bad depth texture mode"); } + } /* for */ } /* if filter */ } -#if 0 -/* - * Experimental depth texture sampling function. - */ -static void -sample_depth_texture2(const GLcontext *ctx, - const struct gl_texture_unit *texUnit, - GLuint n, const GLfloat texcoords[][4], - GLchan texel[][4]) -{ - const struct gl_texture_object *texObj = texUnit->_Current; - const GLint baseLevel = texObj->BaseLevel; - const struct gl_texture_image *texImage = texObj->Image[0][baseLevel]; - const GLuint width = texImage->Width; - const GLuint height = texImage->Height; - GLchan ambient; - GLboolean lequal, gequal; - - if (texObj->Target != GL_TEXTURE_2D) { - _mesa_problem(ctx, "only 2-D depth textures supported at this time"); - return; - } - - if (texObj->MinFilter != texObj->MagFilter) { - _mesa_problem(ctx, "mipmapped depth textures not supported at this time"); - return; - } - - /* XXX the GL_SGIX_shadow extension spec doesn't say what to do if - * GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object - * isn't a depth texture. - */ - if (texImage->TexFormat->BaseFormat != GL_DEPTH_COMPONENT) { - _mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture"); - return; - } - - UNCLAMPED_FLOAT_TO_CHAN(ambient, tObj->ShadowAmbient); - - if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) { - lequal = GL_TRUE; - gequal = GL_FALSE; - } - else { - lequal = GL_FALSE; - gequal = GL_TRUE; - } - - { - GLuint i; - for (i = 0; i < n; i++) { - const GLint K = 3; - GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count; - GLfloat w; - GLchan lum; - col = nearest_texel_location(texObj->WrapS, img, width, - texcoords[i][0]); - row = nearest_texel_location(texObj->WrapT, img, height, - texcoords[i][1]); - - imin = col - K; - imax = col + K; - jmin = row - K; - jmax = row + K; - - if (imin < 0) imin = 0; - if (imax >= width) imax = width - 1; - if (jmin < 0) jmin = 0; - if (jmax >= height) jmax = height - 1; - - samples = (imax - imin + 1) * (jmax - jmin + 1); - count = 0; - for (jj = jmin; jj <= jmax; jj++) { - for (ii = imin; ii <= imax; ii++) { - GLfloat depthSample; - texImage->FetchTexelf(texImage, ii, jj, 0, &depthSample); - if ((depthSample <= r[i] && lequal) || - (depthSample >= r[i] && gequal)) { - count++; - } - } - } - - w = (GLfloat) count / (GLfloat) samples; - w = CHAN_MAXF - w * (CHAN_MAXF - (GLfloat) ambient); - lum = (GLint) w; - - texel[i][RCOMP] = lum; - texel[i][GCOMP] = lum; - texel[i][BCOMP] = lum; - texel[i][ACOMP] = CHAN_MAX; - } - } -} -#endif - - /** * We use this function when a texture object is in an "incomplete" state. * When a fragment program attempts to sample an incomplete texture we @@ -3263,7 +3122,7 @@ static void null_sample_func( GLcontext *ctx, const struct gl_texture_object *tObj, GLuint n, const GLfloat texcoords[][4], const GLfloat lambda[], - GLchan rgba[][4]) + GLfloat rgba[][4]) { GLuint i; (void) ctx; diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c index 16b00b9fa1..f9ff9ad6a4 100644 --- a/src/mesa/swrast/s_texstore.c +++ b/src/mesa/swrast/s_texstore.c @@ -67,7 +67,6 @@ static GLvoid * read_color_image( GLcontext *ctx, GLint x, GLint y, GLenum type, GLsizei width, GLsizei height ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer; const GLint pixelSize = _mesa_bytes_per_pixel(GL_RGBA, type); const GLint stride = width * pixelSize; @@ -78,7 +77,7 @@ read_color_image( GLcontext *ctx, GLint x, GLint y, GLenum type, if (!image) return NULL; - RENDER_START(swrast, ctx); + swrast_render_start(ctx); dst = image; for (row = 0; row < height; row++) { @@ -86,7 +85,7 @@ read_color_image( GLcontext *ctx, GLint x, GLint y, GLenum type, dst += stride; } - RENDER_FINISH(swrast, ctx); + swrast_render_finish(ctx); return image; } @@ -101,7 +100,6 @@ read_depth_image( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height ) { struct gl_renderbuffer *rb = ctx->ReadBuffer->_DepthBuffer; - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint *image, *dst; GLint i; @@ -109,7 +107,7 @@ read_depth_image( GLcontext *ctx, GLint x, GLint y, if (!image) return NULL; - RENDER_START(swrast, ctx); + swrast_render_start(ctx); dst = image; for (i = 0; i < height; i++) { @@ -117,7 +115,7 @@ read_depth_image( GLcontext *ctx, GLint x, GLint y, dst += width; } - RENDER_FINISH(swrast, ctx); + swrast_render_finish(ctx); return image; } @@ -132,7 +130,6 @@ read_depth_stencil_image(GLcontext *ctx, GLint x, GLint y, { struct gl_renderbuffer *depthRb = ctx->ReadBuffer->_DepthBuffer; struct gl_renderbuffer *stencilRb = ctx->ReadBuffer->_StencilBuffer; - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint *image, *dst; GLint i; @@ -143,7 +140,7 @@ read_depth_stencil_image(GLcontext *ctx, GLint x, GLint y, if (!image) return NULL; - RENDER_START(swrast, ctx); + swrast_render_start(ctx); /* read from depth buffer */ dst = image; @@ -205,7 +202,7 @@ read_depth_stencil_image(GLcontext *ctx, GLint x, GLint y, dst += width; } - RENDER_FINISH(swrast, ctx); + swrast_render_finish(ctx); return image; } diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index a2e8433e27..1ab0e19f92 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -35,6 +35,7 @@ #include "main/imports.h" #include "main/macros.h" #include "main/texformat.h" +#include "shader/prog_instruction.h" #include "s_aatriangle.h" #include "s_context.h" @@ -43,8 +44,9 @@ #include "s_triangle.h" -/* - * Just used for feedback mode. +/** + * Test if a triangle should be culled. Used for feedback and selection mode. + * \return GL_TRUE if the triangle is to be culled, GL_FALSE otherwise. */ GLboolean _swrast_culltriangle( GLcontext *ctx, @@ -52,16 +54,17 @@ _swrast_culltriangle( GLcontext *ctx, const SWvertex *v1, const SWvertex *v2 ) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); GLfloat ex = v1->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0]; GLfloat ey = v1->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1]; GLfloat fx = v2->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0]; GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1]; GLfloat c = ex*fy-ey*fx; - if (c * SWRAST_CONTEXT(ctx)->_BackfaceCullSign > 0) - return 0; + if (c * swrast->_BackfaceSign * swrast->_BackfaceCullSign <= 0.0F) + return GL_FALSE; - return 1; + return GL_TRUE; } @@ -131,7 +134,8 @@ _swrast_culltriangle( GLcontext *ctx, #define SETUP_CODE \ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; \ - struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \ + struct gl_texture_object *obj = \ + ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const GLint b = obj->BaseLevel; \ const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \ const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \ @@ -182,7 +186,8 @@ _swrast_culltriangle( GLcontext *ctx, #define SETUP_CODE \ struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0]; \ - struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \ + struct gl_texture_object *obj = \ + ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const GLint b = obj->BaseLevel; \ const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \ const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \ @@ -263,10 +268,7 @@ affine_span(GLcontext *ctx, SWspan *span, struct affine_info *info) { GLchan sample[4]; /* the filtered texture sample */ - const GLuint texEnableSave = ctx->Texture._EnabledUnits; - - /* Disable tex units so they're not re-applied in swrast_write_rgba_span */ - ctx->Texture._EnabledUnits = 0x0; + const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits; /* Instead of defining a function for each mode, a test is done * between the outer and inner loops. This is to reduce code size @@ -396,6 +398,9 @@ affine_span(GLcontext *ctx, SWspan *span, GLuint i; GLchan *dest = span->array->rgba[0]; + /* Disable tex units so they're not re-applied in swrast_write_rgba_span */ + ctx->Texture._EnabledCoordUnits = 0x0; + span->intTex[0] -= FIXED_HALF; span->intTex[1] -= FIXED_HALF; switch (info->filter) { @@ -501,7 +506,7 @@ affine_span(GLcontext *ctx, SWspan *span, _swrast_write_rgba_span(ctx, span); /* re-enable texture units */ - ctx->Texture._EnabledUnits = texEnableSave; + ctx->Texture._EnabledCoordUnits = texEnableSave; #undef SPAN_NEAREST #undef SPAN_LINEAR @@ -523,7 +528,8 @@ affine_span(GLcontext *ctx, SWspan *span, #define SETUP_CODE \ struct affine_info info; \ struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ - struct gl_texture_object *obj = unit->Current2D; \ + struct gl_texture_object *obj = \ + ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const GLint b = obj->BaseLevel; \ const GLfloat twidth = (GLfloat) obj->Image[0][b]->Width; \ const GLfloat theight = (GLfloat) obj->Image[0][b]->Height; \ @@ -660,8 +666,8 @@ fast_persp_span(GLcontext *ctx, SWspan *span, GLfloat tex_coord[3], tex_step[3]; GLchan *dest = span->array->rgba[0]; - const GLuint savedTexEnable = ctx->Texture._EnabledUnits; - ctx->Texture._EnabledUnits = 0; + const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits; + ctx->Texture._EnabledCoordUnits = 0; tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0] * (info->smask + 1); tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1); @@ -774,7 +780,7 @@ fast_persp_span(GLcontext *ctx, SWspan *span, #undef SPAN_LINEAR /* restore state */ - ctx->Texture._EnabledUnits = savedTexEnable; + ctx->Texture._EnabledCoordUnits = texEnableSave; } @@ -793,7 +799,8 @@ fast_persp_span(GLcontext *ctx, SWspan *span, #define SETUP_CODE \ struct persp_info info; \ const struct gl_texture_unit *unit = ctx->Texture.Unit+0; \ - const struct gl_texture_object *obj = unit->Current2D; \ + struct gl_texture_object *obj = \ + ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; \ const GLint b = obj->BaseLevel; \ info.texture = (const GLchan *) obj->Image[0][b]->Data; \ info.twidth_log2 = obj->Image[0][b]->WidthLog2; \ @@ -1017,7 +1024,7 @@ _swrast_choose_triangle( GLcontext *ctx ) ctx->Depth.Test && ctx->Depth.Mask == GL_FALSE && ctx->Depth.Func == GL_LESS && - !ctx->Stencil.Enabled) { + !ctx->Stencil._Enabled) { if ((rgbmode && ctx->Color.ColorMask[0] == 0 && ctx->Color.ColorMask[1] == 0 && @@ -1049,7 +1056,8 @@ _swrast_choose_triangle( GLcontext *ctx ) const struct gl_texture_image *texImg; GLenum minFilter, magFilter, envMode; GLint format; - texObj2D = ctx->Texture.Unit[0].Current2D; + texObj2D = ctx->Texture.Unit[0].CurrentTex[TEXTURE_2D_INDEX]; + texImg = texObj2D ? texObj2D->Image[0][texObj2D->BaseLevel] : NULL; format = texImg ? texImg->TexFormat->MesaFormat : -1; minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0; @@ -1063,6 +1071,7 @@ _swrast_choose_triangle( GLcontext *ctx ) && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && texObj2D->WrapS == GL_REPEAT && texObj2D->WrapT == GL_REPEAT + && texObj2D->_Swizzle == SWIZZLE_NOOP && texImg->_IsPowerOfTwo && texImg->Border == 0 && texImg->Width == texImg->RowStride @@ -1070,7 +1079,8 @@ _swrast_choose_triangle( GLcontext *ctx ) && minFilter == magFilter && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR && !swrast->_FogEnabled - && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) { + && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT + && ctx->Texture.Unit[0].EnvMode != GL_COMBINE4_NV) { if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) { if (minFilter == GL_NEAREST && format == MESA_FORMAT_RGB diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 047f7991e6..a85d69bfbf 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -33,6 +33,7 @@ #define SWRAST_H #include "main/mtypes.h" +#include "swrast_features.h" /** * \struct SWvertex @@ -75,6 +76,12 @@ typedef struct { } SWvertex; +/** + * Fixed point data type. + */ +typedef int GLfixed; + + #define FRAG_ATTRIB_CI FRAG_ATTRIB_COL0 @@ -96,28 +103,6 @@ extern struct swrast_device_driver * _swrast_GetDeviceDriverReference( GLcontext *ctx ); extern void -_swrast_Bitmap( GLcontext *ctx, - GLint px, GLint py, - GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap ); - -extern void -_swrast_CopyPixels( GLcontext *ctx, - GLint srcx, GLint srcy, - GLint destx, GLint desty, - GLsizei width, GLsizei height, - GLenum type ); - -extern void -_swrast_DrawPixels( GLcontext *ctx, - GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ); - -extern void _swrast_ReadPixels( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, @@ -133,10 +118,6 @@ _swrast_BlitFramebuffer(GLcontext *ctx, extern void _swrast_Clear(GLcontext *ctx, GLbitfield buffers); -extern void -_swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value); - - /* Reset the stipple counter */ @@ -202,28 +183,6 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ); /* - * Imaging fallbacks (a better solution should be found, perhaps - * moving all the imaging fallback code to a new module) - */ -extern void -_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, - GLenum internalFormat, - GLint x, GLint y, GLsizei width, - GLsizei height); -extern void -_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, - GLenum internalFormat, - GLint x, GLint y, GLsizei width); -extern void -_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, - GLint x, GLint y, GLsizei width); -extern void -_swrast_CopyColorTable( GLcontext *ctx, - GLenum target, GLenum internalformat, - GLint x, GLint y, GLsizei width); - - -/* * Texture fallbacks. Could also live in a new module * with the rest of the texture store fallbacks? */ @@ -260,12 +219,6 @@ extern void _swrast_eject_texture_images(GLcontext *ctx); -#if FEATURE_MESA_program_debug -extern void -_swrast_get_program_register(GLcontext *, enum register_file file, - GLuint index, GLfloat val[4]); -#endif /* FEATURE_MESA_program_debug */ - /** * The driver interface for the software rasterizer. @@ -287,6 +240,4 @@ struct swrast_device_driver { void (*SpanRenderFinish)(GLcontext *ctx); }; - - -#endif +#endif /* SWRAST_H */ diff --git a/src/mesa/swrast/swrast_features.h b/src/mesa/swrast/swrast_features.h new file mode 100644 index 0000000000..486d607eb9 --- /dev/null +++ b/src/mesa/swrast/swrast_features.h @@ -0,0 +1,142 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5 + * + * Copyright (C) 1999-2006 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"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +/** + * \file swrast/swrast_features.h + * \brief Public interface to the software rasterization functions. + * \author Keith Whitwell <keith@tungstengraphics.com> + */ + +#ifndef SWRAST_FEATURES_H +#define SWRAST_FEATURES_H + +#include "main/mtypes.h" + + +#if FEATURE_accum + +extern void +_swrast_Accum(GLcontext *ctx, GLenum op, GLfloat value); + +#endif + + +/* + * Imaging fallbacks (a better solution should be found, perhaps + * moving all the imaging fallback code to a new module) + */ +#if FEATURE_convolve + +extern void +_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, + GLsizei height); + +extern void +_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target, + GLenum internalFormat, + GLint x, GLint y, GLsizei width); + +#endif + + +#if FEATURE_colortable + +extern void +_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start, + GLint x, GLint y, GLsizei width); + +extern void +_swrast_CopyColorTable( GLcontext *ctx, + GLenum target, GLenum internalformat, + GLint x, GLint y, GLsizei width); + +#define _swrast_UpdateTexturePalette NULL + +#endif + + +#if FEATURE_drawpix + +extern void +_swrast_Bitmap( GLcontext *ctx, + GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ); + +extern void +_swrast_CopyPixels( GLcontext *ctx, + GLint srcx, GLint srcy, + GLint destx, GLint desty, + GLsizei width, GLsizei height, + GLenum type ); + +extern void +_swrast_DrawPixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ); + +#else /* FEATURE_drawpix */ + +static INLINE void +_swrast_Bitmap( GLcontext *ctx, + GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + ASSERT_NO_FEATURE(); +} + +static INLINE void +_swrast_CopyPixels( GLcontext *ctx, + GLint srcx, GLint srcy, + GLint destx, GLint desty, + GLsizei width, GLsizei height, + GLenum type ) +{ + ASSERT_NO_FEATURE(); +} + +static INLINE void +_swrast_DrawPixels( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + ASSERT_NO_FEATURE(); +} + +#endif + + +#endif /* SWRAST_FEATURES_H */ |