diff options
Diffstat (limited to 'src/mesa/swrast/s_context.c')
-rw-r--r-- | src/mesa/swrast/s_context.c | 160 |
1 files changed, 123 insertions, 37 deletions
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index f5f04b05f5a..00702b43013 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -2,7 +2,7 @@ * Mesa 3-D graphics library * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -31,7 +31,7 @@ #include "context.h" #include "colormac.h" #include "mtypes.h" -#include "program.h" +#include "prog_statevars.h" #include "teximage.h" #include "swrast.h" #include "s_blend.h" @@ -98,11 +98,7 @@ _swrast_update_rasterflags( GLcontext *ctx ) rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ } - if (ctx->FragmentProgram._Enabled) { - rasterMask |= FRAGPROG_BIT; - } - - if (ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->FragmentProgram._Current) { rasterMask |= FRAGPROG_BIT; } @@ -129,27 +125,28 @@ _swrast_update_rasterflags( GLcontext *ctx ) static void _swrast_update_polygon( GLcontext *ctx ) { - GLfloat backface_sign = 1; + GLfloat backface_sign; if (ctx->Polygon.CullFlag) { - backface_sign = 1; - switch(ctx->Polygon.CullFaceMode) { + backface_sign = 1.0; + switch (ctx->Polygon.CullFaceMode) { case GL_BACK: - if(ctx->Polygon.FrontFace==GL_CCW) - backface_sign = -1; + if (ctx->Polygon.FrontFace == GL_CCW) + backface_sign = -1.0; break; case GL_FRONT: - if(ctx->Polygon.FrontFace!=GL_CCW) - backface_sign = -1; + if (ctx->Polygon.FrontFace != GL_CCW) + backface_sign = -1.0; break; - default: case GL_FRONT_AND_BACK: - backface_sign = 0; + /* fallthrough */ + default: + backface_sign = 0.0; break; } } else { - backface_sign = 0; + backface_sign = 0.0; } SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign; @@ -165,7 +162,7 @@ _swrast_update_fog_hint( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); swrast->_PreferPixelFog = (!swrast->AllowVertexFog || - ctx->FragmentProgram._Enabled || /* not _Active! */ + ctx->FragmentProgram._Current || (ctx->Hint.Fog == GL_NICEST && swrast->AllowPixelFog)); } @@ -198,20 +195,14 @@ static void _swrast_update_fog_state( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; /* determine if fog is needed, and if so, which fog mode */ swrast->_FogEnabled = GL_FALSE; - if (ctx->ShaderObjects._FragmentShaderPresent) { - swrast->_FogEnabled = GL_FALSE; - } - else if (ctx->FragmentProgram._Enabled) { - if (ctx->FragmentProgram._Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) { - const struct gl_fragment_program *fp - = ctx->FragmentProgram._Current; - if (fp->FogOption != GL_NONE) { - swrast->_FogEnabled = GL_TRUE; - swrast->_FogMode = fp->FogOption; - } + if (fp && fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + if (fp->FogOption != GL_NONE) { + swrast->_FogEnabled = GL_TRUE; + swrast->_FogMode = fp->FogOption; } } else if (ctx->Fog.Enabled) { @@ -228,8 +219,8 @@ _swrast_update_fog_state( GLcontext *ctx ) static void _swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState) { - if (ctx->FragmentProgram._Enabled) { - const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; + 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. @@ -304,7 +295,7 @@ _swrast_validate_triangle( GLcontext *ctx, if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { /* separate specular color, but no texture */ swrast->SpecTriangle = swrast->Triangle; swrast->Triangle = _swrast_add_spec_terms_triangle; @@ -328,7 +319,7 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { swrast->SpecLine = swrast->Line; swrast->Line = _swrast_add_spec_terms_line; } @@ -351,7 +342,7 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { swrast->SpecPoint = swrast->Point; swrast->Point = _swrast_add_spec_terms_point; } @@ -505,11 +496,96 @@ _swrast_update_texture_samplers(GLcontext *ctx) 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 + * function that just returns opaque black (0,0,0,1). + */ swrast->TextureSample[u] = _swrast_choose_texture_sample_func(ctx, tObj); } } +/** + * Update the swrast->_FragmentAttribs field. + */ +static void +_swrast_update_fragment_attribs(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (ctx->FragmentProgram._Current) { + swrast->_FragmentAttribs + = ctx->FragmentProgram._Current->Base.InputsRead; + } + else { + GLuint u; + swrast->_FragmentAttribs = 0x0; + + if (ctx->Depth.Test) + swrast->_FragmentAttribs |= FRAG_BIT_WPOS; + if (NEED_SECONDARY_COLOR(ctx)) + swrast->_FragmentAttribs |= FRAG_BIT_COL1; + if (swrast->_FogEnabled) + swrast->_FragmentAttribs |= FRAG_BIT_FOGC; + + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + swrast->_FragmentAttribs |= FRAG_BIT_TEX(u); + } + } + } + + /* Find lowest, highest bit set in _FragmentAttribs */ + { + GLuint bits = swrast->_FragmentAttribs; + GLuint i = 0;; + while (bits) { + i++; + bits = bits >> 1; + } + swrast->_MaxFragmentAttrib = i; + swrast->_MinFragmentAttrib = FRAG_ATTRIB_TEX0; /* XXX temporary */ + } +} + + +/** + * Update the swrast->_ColorOutputsMask which indicates which color + * renderbuffers (aka rendertargets) are being written to by the current + * fragment program. + * We also take glDrawBuffers() into account to skip outputs that are + * set to GL_NONE. + */ +static void +_swrast_update_color_outputs(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_framebuffer *fb = ctx->DrawBuffer; + + swrast->_ColorOutputsMask = 0; + swrast->_NumColorOutputs = 0; + + if (ctx->FragmentProgram._Current) { + const GLbitfield outputsWritten + = ctx->FragmentProgram._Current->Base.OutputsWritten; + GLuint output; + for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) { + if ((outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) + && (fb->_NumColorDrawBuffers[output] > 0)) { + swrast->_ColorOutputsMask |= (1 << output); + swrast->_NumColorOutputs = output + 1; + } + } + } + if (swrast->_ColorOutputsMask == 0x0) { + /* no fragment program, or frag prog didn't write to gl_FragData[] */ + if (fb->_NumColorDrawBuffers[0] > 0) { + swrast->_ColorOutputsMask = 0x1; + swrast->_NumColorOutputs = 1; + } + } +} + + void _swrast_validate_derived( GLcontext *ctx ) { @@ -550,6 +626,15 @@ _swrast_validate_derived( GLcontext *ctx ) if (swrast->NewState & _SWRAST_NEW_RASTERMASK) _swrast_update_rasterflags( ctx ); + if (swrast->NewState & (_NEW_DEPTH | + _NEW_FOG | + _NEW_PROGRAM | + _NEW_TEXTURE)) + _swrast_update_fragment_attribs(ctx); + + if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS)) + _swrast_update_color_outputs(ctx); + swrast->NewState = 0; swrast->StateChanges = 0; swrast->InvalidateState = _swrast_invalidate_state; @@ -707,7 +792,6 @@ _swrast_CreateContext( GLcontext *ctx ) /* init point span buffer */ swrast->PointSpan.primitive = GL_POINT; - swrast->PointSpan.start = 0; swrast->PointSpan.end = 0; swrast->PointSpan.facing = 0; swrast->PointSpan.array = swrast->SpanArrays; @@ -810,8 +894,10 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) if (ctx->Texture.Unit[i]._ReallyEnabled) _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, - v->texcoord[i][0], v->texcoord[i][1], - v->texcoord[i][2], v->texcoord[i][3]); + v->attrib[FRAG_ATTRIB_TEX0 + i][0], + v->attrib[FRAG_ATTRIB_TEX0 + i][1], + v->attrib[FRAG_ATTRIB_TEX0 + i][2], + v->attrib[FRAG_ATTRIB_TEX0 + i][3]); #if CHAN_TYPE == GL_FLOAT _mesa_debug(ctx, "color %f %f %f %f\n", |