/** * Determine if we can defer texturing/shading until after Z/stencil * testing. This potentially allows us to skip texturing/shading for * lots of fragments. */ static void _swrast_update_deferred_texture(struct gl_context *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); if (ctx->Color.AlphaEnabled) { /* alpha test depends on post-texture/shader colors */ swrast->_DeferredTexture = GL_FALSE; } else { GLboolean use_fprog = _swrast_use_fragment_program(ctx); const struct gl_fragment_program *fprog = ctx->FragmentProgram._Current; if (use_fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH))) { /* Z comes from fragment program/shader */ swrast->_DeferredTexture = GL_FALSE; } else if (use_fprog && fprog->UsesKill) { swrast->_DeferredTexture = GL_FALSE; } else if (ctx->Query.CurrentOcclusionObject) { /* occlusion query depends on shader discard/kill results */ swrast->_DeferredTexture = GL_FALSE; } else { swrast->_DeferredTexture = GL_TRUE; } } }
/** * Update state for running fragment programs. Basically, load the * program parameters with current state values. */ static void _swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState) { if (!_swrast_use_fragment_program(ctx)) return; _mesa_load_state_parameters(ctx, ctx->FragmentProgram._Current->Base.Parameters); }
/** * Update the _PreferPixelFog field to indicate if we need to compute * fog blend factors (from the fog coords) per-fragment. */ static void _swrast_update_fog_hint( struct gl_context *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); swrast->_PreferPixelFog = (!swrast->AllowVertexFog || _swrast_use_fragment_program(ctx) || (ctx->Hint.Fog == GL_NICEST && swrast->AllowPixelFog)); }
/** * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, * swrast->_ActiveAtttribMask. */ static void _swrast_update_active_attribs(struct gl_context *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLbitfield64 attribsMask; /* * Compute _ActiveAttribsMask = which fragment attributes are needed. */ if (_swrast_use_fragment_program(ctx)) { /* fragment program/shader */ attribsMask = ctx->FragmentProgram._Current->Base.InputsRead; attribsMask &= ~VARYING_BIT_POS; /* WPOS is always handled specially */ } else if (ctx->ATIFragmentShader._Enabled) { attribsMask = VARYING_BIT_COL0 | VARYING_BIT_COL1 | VARYING_BIT_FOGC | VARYING_BITS_TEX_ANY; } else { /* fixed function */ attribsMask = 0x0; #if CHAN_TYPE == GL_FLOAT attribsMask |= VARYING_BIT_COL0; #endif if (ctx->Fog.ColorSumEnabled || (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { attribsMask |= VARYING_BIT_COL1; } if (swrast->_FogEnabled) attribsMask |= VARYING_BIT_FOGC; attribsMask |= (ctx->Texture._EnabledCoordUnits << VARYING_SLOT_TEX0); } swrast->_ActiveAttribMask = attribsMask; /* Update _ActiveAttribs[] list */ { GLuint i, num = 0; for (i = 0; i < VARYING_SLOT_MAX; i++) { if (attribsMask & BITFIELD64_BIT(i)) { swrast->_ActiveAttribs[num++] = i; /* how should this attribute be interpolated? */ if (i == VARYING_SLOT_COL0 || i == VARYING_SLOT_COL1) swrast->_InterpMode[i] = ctx->Light.ShadeModel; else swrast->_InterpMode[i] = GL_SMOOTH; } } swrast->_NumActiveAttribs = num; } }
/** * Update swrast->_FogColor and swrast->_FogEnable values. */ static void _swrast_update_fog_state( struct gl_context *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; assert(fp == NULL || fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB); /* determine if fog is needed, and if so, which fog mode */ swrast->_FogEnabled = (!_swrast_use_fragment_program(ctx) && ctx->Fog.Enabled); }
/** * 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(struct gl_context *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._MaxEnabledTexImageUnit == -1 && !_swrast_use_fragment_program(ctx) && !ctx->ATIFragmentShader._Enabled); }
/** * Determine which line drawing function to use given the current * rendering context. * * Please update the summary flag _SWRAST_NEW_LINE if you add or remove * tests to this code. */ void _swrast_choose_line( struct gl_context *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLboolean specular = (ctx->Fog.ColorSumEnabled || (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); if (ctx->RenderMode == GL_RENDER) { if (ctx->Line.SmoothFlag) { /* antialiased lines */ _swrast_choose_aa_line_function(ctx); ASSERT(swrast->Line); } else if (ctx->Texture._EnabledCoordUnits || _swrast_use_fragment_program(ctx) || swrast->_FogEnabled || specular) { USE(general_line); } else if (ctx->Depth.Test || ctx->Line.Width != 1.0 || ctx->Line.StippleFlag) { /* no texture, but Z, fog, width>1, stipple, etc. */ #if CHAN_BITS == 32 USE(general_line); #else USE(rgba_line); #endif } else { ASSERT(!ctx->Depth.Test); ASSERT(ctx->Line.Width == 1.0); /* simple lines */ USE(simple_no_z_rgba_line); } } else if (ctx->RenderMode == GL_FEEDBACK) { USE(_swrast_feedback_line); } else { ASSERT(ctx->RenderMode == GL_SELECT); USE(_swrast_select_line); } }
/* * Examine GL state and set swrast->Triangle to an * appropriate antialiased triangle rasterizer function. */ void _swrast_set_aa_triangle_function(struct gl_context *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); ASSERT(ctx->Polygon.SmoothFlag); if (ctx->Texture._EnabledCoordUnits != 0 || _swrast_use_fragment_program(ctx) || swrast->_FogEnabled || _mesa_need_secondary_color(ctx)) { SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri; } else { SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri; } ASSERT(SWRAST_CONTEXT(ctx)->Triangle); }
void _swrast_choose_aa_line_function(struct gl_context *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); ASSERT(ctx->Line.SmoothFlag); if (ctx->Texture._EnabledCoordUnits != 0 || _swrast_use_fragment_program(ctx) || (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) || ctx->Fog.ColorSumEnabled || swrast->_FogEnabled) { swrast->Line = aa_general_rgba_line; } else { swrast->Line = aa_rgba_line; } }
/** * Recompute the value of swrast->_RasterMask, etc. according to * the current context. The _RasterMask field can be easily tested by * drivers to determine certain basic GL state (does the primitive need * stenciling, logic-op, fog, etc?). */ static void _swrast_update_rasterflags( struct gl_context *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLbitfield rasterMask = 0; GLuint i; if (ctx->Color.AlphaEnabled) rasterMask |= ALPHATEST_BIT; if (ctx->Color.BlendEnabled) rasterMask |= BLEND_BIT; if (ctx->Depth.Test) rasterMask |= DEPTH_BIT; if (swrast->_FogEnabled) rasterMask |= FOG_BIT; if (ctx->Scissor.EnableFlags) rasterMask |= CLIP_BIT; if (ctx->Stencil._Enabled) rasterMask |= STENCIL_BIT; for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { if (!ctx->Color.ColorMask[i][0] || !ctx->Color.ColorMask[i][1] || !ctx->Color.ColorMask[i][2] || !ctx->Color.ColorMask[i][3]) { rasterMask |= MASKING_BIT; break; } } if (ctx->Color.ColorLogicOpEnabled) rasterMask |= LOGIC_OP_BIT; if (ctx->Texture._MaxEnabledTexImageUnit >= 0) rasterMask |= TEXTURE_BIT; if ( ctx->ViewportArray[0].X < 0 || ctx->ViewportArray[0].X + ctx->ViewportArray[0].Width > (GLfloat) ctx->DrawBuffer->Width || ctx->ViewportArray[0].Y < 0 || ctx->ViewportArray[0].Y + ctx->ViewportArray[0].Height > (GLfloat) ctx->DrawBuffer->Height) { rasterMask |= CLIP_BIT; } if (ctx->Query.CurrentOcclusionObject) rasterMask |= OCCLUSION_BIT; /* If we're not drawing to exactly one color buffer set the * MULTI_DRAW_BIT flag. Also set it if we're drawing to no * buffers or the RGBA or CI mask disables all writes. */ if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) { /* more than one color buffer designated for writing (or zero buffers) */ rasterMask |= MULTI_DRAW_BIT; } for (i = 0; i < ctx->Const.MaxDrawBuffers; i++) { if (ctx->Color.ColorMask[i][0] + ctx->Color.ColorMask[i][1] + ctx->Color.ColorMask[i][2] + ctx->Color.ColorMask[i][3] == 0) { rasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */ break; } } if (_swrast_use_fragment_program(ctx)) { rasterMask |= FRAGPROG_BIT; } if (ctx->ATIFragmentShader._Enabled) { rasterMask |= ATIFRAGSHADER_BIT; } #if CHAN_TYPE == GL_FLOAT if (ctx->Color.ClampFragmentColor == GL_TRUE) { rasterMask |= CLAMPING_BIT; } #endif SWRAST_CONTEXT(ctx)->_RasterMask = rasterMask; }