/*
* Mesa 3-D graphics library
- * Version: 6.5.3
+ * Version: 7.1
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
rasterMask |= FRAGPROG_BIT;
}
- if (ctx->Shader._FragmentShaderPresent) {
- rasterMask |= FRAGPROG_BIT;
- }
-
if (ctx->ATIFragmentShader._Enabled) {
rasterMask |= ATIFRAGSHADER_BIT;
}
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;
/**
* Update the _PreferPixelFog field to indicate if we need to compute
- * fog factors per-fragment.
+ * fog blend factors (from the fog coords) per-fragment.
*/
static void
_swrast_update_fog_hint( GLcontext *ctx )
}
+/**
+ * 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(GLcontext *ctx)
+{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
+ if (ctx->Color.AlphaEnabled) {
+ /* alpha test depends on post-texture/shader colors */
+ swrast->_DeferredTexture = GL_FALSE;
+ }
+ else {
+ const struct gl_fragment_program *fprog
+ = ctx->FragmentProgram._Current;
+ if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR))) {
+ /* Z comes from fragment program/shader */
+ 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 swrast->_FogColor and swrast->_FogEnable values.
*/
swrast->Line = _swrast_add_spec_terms_line;
}
-
swrast->Line( ctx, v0, v1 );
}
GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
GLuint face;
for (face = 0; face < numFaces; face++) {
- GLuint lvl;
+ GLint lvl;
for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {
struct gl_texture_image *texImg = texObj->Image[face][lvl];
if (texImg && !texImg->Data) {
GLuint numFaces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
GLuint face;
for (face = 0; face < numFaces; face++) {
- GLuint lvl;
+ GLint lvl;
for (lvl = texObj->BaseLevel; lvl <= texObj->_MaxLevel; lvl++) {
struct gl_texture_image *texImg = texObj->Image[face][lvl];
if (texImg && texImg->Data) {
}
-static void
+void
_swrast_update_texture_samplers(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
/**
- * Update the swrast->_FragmentAttribs field.
+ * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs,
+ * swrast->_ActiveAtttribMask.
*/
static void
-_swrast_update_fragment_attribs(GLcontext *ctx)
+_swrast_update_active_attribs(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
+ GLuint attribsMask;
+
+ /*
+ * Compute _ActiveAttribsMask = which fragment attributes are needed.
+ */
if (ctx->FragmentProgram._Current) {
- swrast->_FragmentAttribs
- = ctx->FragmentProgram._Current->Base.InputsRead;
+ /* fragment program/shader */
+ attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
+ attribsMask &= ~FRAG_BIT_WPOS; /* WPOS is always handled specially */
+ }
+ else if (ctx->ATIFragmentShader._Enabled) {
+ attribsMask = ~0; /* XXX fix me */
}
else {
- GLuint u;
- swrast->_FragmentAttribs = 0x0;
+ /* fixed function */
+ attribsMask = 0x0;
+
+#if CHAN_TYPE == GL_FLOAT
+ attribsMask |= FRAG_BIT_COL0;
+#endif
+
+ if (ctx->Fog.ColorSumEnabled ||
+ (ctx->Light.Enabled &&
+ ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
+ attribsMask |= FRAG_BIT_COL1;
+ }
- 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;
+ attribsMask |= FRAG_BIT_FOGC;
+
+ attribsMask |= (ctx->Texture._EnabledUnits << FRAG_ATTRIB_TEX0);
+ }
- for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
- if (ctx->Texture.Unit[u]._ReallyEnabled) {
- swrast->_FragmentAttribs |= FRAG_BIT_TEX(u);
+ swrast->_ActiveAttribMask = attribsMask;
+
+ /* Update _ActiveAttribs[] list */
+ {
+ GLuint i, num = 0;
+ for (i = 0; i < FRAG_ATTRIB_MAX; i++) {
+ if (attribsMask & (1 << i)) {
+ swrast->_ActiveAttribs[num++] = i;
+ /* how should this attribute be interpolated? */
+ if (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1)
+ swrast->_InterpMode[i] = ctx->Light.ShadeModel;
+ else
+ swrast->_InterpMode[i] = GL_SMOOTH;
}
}
+ swrast->_NumActiveAttribs = num;
}
+}
- /* Find lowest, highest bit set in _FragmentAttribs */
- {
- GLuint bits = swrast->_FragmentAttribs;
- GLuint i = 0;;
- while (bits) {
- i++;
- bits = bits >> 1;
+
+/**
+ * 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;
}
- swrast->_MaxFragmentAttrib = i;
- swrast->_MinFragmentAttrib = FRAG_ATTRIB_TEX0; /* XXX temporary */
}
}
_NEW_PROGRAM))
_swrast_update_fragment_program( ctx, swrast->NewState );
- if (swrast->NewState & _NEW_TEXTURE)
+ if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) {
_swrast_update_texture_samplers( ctx );
+ _swrast_validate_texture_images(ctx);
+ }
- if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM))
- _swrast_validate_texture_images( ctx );
+ if (swrast->NewState & (_NEW_COLOR | _NEW_PROGRAM))
+ _swrast_update_deferred_texture(ctx);
if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
_swrast_update_rasterflags( ctx );
if (swrast->NewState & (_NEW_DEPTH |
_NEW_FOG |
+ _NEW_LIGHT |
_NEW_PROGRAM |
_NEW_TEXTURE))
- _swrast_update_fragment_attribs(ctx);
+ _swrast_update_active_attribs(ctx);
+
+ if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS))
+ _swrast_update_color_outputs(ctx);
swrast->NewState = 0;
swrast->StateChanges = 0;
}
swrast->SpanArrays->ChanType = CHAN_TYPE;
#if CHAN_TYPE == GL_UNSIGNED_BYTE
- swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz1.rgba;
- swrast->SpanArrays->spec = swrast->SpanArrays->color.sz1.spec;
+ swrast->SpanArrays->rgba = swrast->SpanArrays->rgba8;
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
- swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz2.rgba;
- swrast->SpanArrays->spec = swrast->SpanArrays->color.sz2.spec;
+ swrast->SpanArrays->rgba = swrast->SpanArrays->rgba16;
#else
- swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz4.rgba;
- swrast->SpanArrays->spec = swrast->SpanArrays->color.sz4.spec;
+ swrast->SpanArrays->rgba = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0];
#endif
/* init point span buffer */
if (SWRAST_DEBUG_VERTICES) {
_mesa_debug(ctx, "win %f %f %f %f\n",
- v->win[0], v->win[1], v->win[2], v->win[3]);
+ v->attrib[FRAG_ATTRIB_WPOS][0],
+ v->attrib[FRAG_ATTRIB_WPOS][1],
+ v->attrib[FRAG_ATTRIB_WPOS][2],
+ v->attrib[FRAG_ATTRIB_WPOS][3]);
for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
if (ctx->Texture.Unit[i]._ReallyEnabled)
#if CHAN_TYPE == GL_FLOAT
_mesa_debug(ctx, "color %f %f %f %f\n",
v->color[0], v->color[1], v->color[2], v->color[3]);
- _mesa_debug(ctx, "spec %f %f %f %f\n",
- v->specular[0], v->specular[1],
- v->specular[2], v->specular[3]);
#else
_mesa_debug(ctx, "color %d %d %d %d\n",
v->color[0], v->color[1], v->color[2], v->color[3]);
- _mesa_debug(ctx, "spec %d %d %d %d\n",
- v->specular[0], v->specular[1],
- v->specular[2], v->specular[3]);
#endif
- _mesa_debug(ctx, "fog %f\n", v->fog);
- _mesa_debug(ctx, "index %d\n", v->index);
+ _mesa_debug(ctx, "spec %g %g %g %g\n",
+ v->attrib[FRAG_ATTRIB_COL1][0],
+ v->attrib[FRAG_ATTRIB_COL1][1],
+ v->attrib[FRAG_ATTRIB_COL1][2],
+ v->attrib[FRAG_ATTRIB_COL1][3]);
+ _mesa_debug(ctx, "fog %f\n", v->attrib[FRAG_ATTRIB_FOGC][0]);
+ _mesa_debug(ctx, "index %d\n", v->attrib[FRAG_ATTRIB_CI][0]);
_mesa_debug(ctx, "pointsize %f\n", v->pointSize);
_mesa_debug(ctx, "\n");
}