From 32340aea1308153dad5c105fc0748aea1e4c37ee Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 24 Oct 2005 19:28:36 +0000 Subject: fragment program writing to result.depth.z was broken --- src/mesa/swrast/s_nvfragprog.c | 15 +++++++++++++-- src/mesa/swrast/s_span.c | 31 ++++++++++++++++++------------- 2 files changed, 31 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index 441d1e8ca7..987163389a 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -1390,6 +1390,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, /* Load input registers */ if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) { GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS]; + ASSERT(span->arrayMask & SPAN_Z); wpos[0] = (GLfloat) span->x + col; wpos[1] = (GLfloat) span->y; wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF; @@ -1397,6 +1398,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, } if (inputsRead & (1 << FRAG_ATTRIB_COL0)) { GLfloat *col0 = machine->Inputs[FRAG_ATTRIB_COL0]; + ASSERT(span->arrayMask & SPAN_RGBA); col0[0] = CHAN_TO_FLOAT(span->array->rgba[col][RCOMP]); col0[1] = CHAN_TO_FLOAT(span->array->rgba[col][GCOMP]); col0[2] = CHAN_TO_FLOAT(span->array->rgba[col][BCOMP]); @@ -1411,6 +1413,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, } if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) { GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC]; + ASSERT(span->arrayMask & SPAN_FOG); fogc[0] = span->array->fog[col]; fogc[1] = 0.0F; fogc[2] = 0.0F; @@ -1479,11 +1482,19 @@ _swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span ) UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], colOut[3]); } /* depth value */ - if (program->OutputsWritten & (1 << FRAG_OUTPUT_DEPR)) - span->array->z[i] = IROUND(ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR][0] * ctx->DrawBuffer->_DepthMaxF); + if (program->OutputsWritten & (1 << FRAG_OUTPUT_DEPR)) { + const GLfloat depth + = ctx->FragmentProgram.Machine.Outputs[FRAG_OUTPUT_DEPR][2]; + span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF); + } } } + if (program->OutputsWritten & (1 << FRAG_OUTPUT_DEPR)) { + span->interpMask &= ~SPAN_Z; + span->arrayMask |= SPAN_Z; + } + ctx->_CurrentProgram = 0; } diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index b6d4098f24..5e26064c64 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -328,6 +328,7 @@ _swrast_span_interpolate_z( const GLcontext *ctx, struct sw_span *span ) zval += span->zStep; } } + span->interpMask &= ~SPAN_Z; span->arrayMask |= SPAN_Z; } @@ -1080,6 +1081,9 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLbitfield origInterpMask = span->interpMask; const GLbitfield origArrayMask = span->arrayMask; + const GLboolean deferredTexture = !(ctx->Color.AlphaEnabled || + ctx->FragmentProgram._Active || + ctx->ATIFragmentShader._Enabled); ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE || span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); @@ -1134,14 +1138,12 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) interpolate_texcoords(ctx, span); } - /* If the alpha test is enabled, we have to compute the fragment colors - * at this point and do the alpha test. - * Else, if alpha test is not enabled, we'll try to defer fragment - * color computation (by interpolation, texture mapping, fragment program) - * until after the Z/stencil tests in the hope that many fragments will - * get culled, leaving less work to do. + /* This is the normal place to compute the resulting fragment color/Z. + * As an optimization, we try to defer this until after Z/stencil + * testing in order to try to avoid computing colors that we won't + * actually need. */ - if (ctx->Color.AlphaEnabled) { + if (!deferredTexture) { /* Now we need the rgba array, fill it in if needed */ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) interpolate_colors(ctx, span); @@ -1153,9 +1155,12 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) interpolate_fog(ctx, span); /* Compute fragment colors with fragment program or texture lookups */ - if (ctx->FragmentProgram._Active) - /* XXX interpolate depth values here??? */ + if (ctx->FragmentProgram._Active) { + /* frag prog may need Z values */ + if (span->interpMask & SPAN_Z) + _swrast_span_interpolate_z(ctx, span); _swrast_exec_fragment_program( ctx, span ); + } else if (ctx->ATIFragmentShader._Enabled) _swrast_exec_fragment_shader( ctx, span ); else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) @@ -1212,11 +1217,11 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span) return; } - /* If the alpha test isn't enabled, we're able to defer computing fragment - * colors (by interpolation, texturing, fragment program) until now. - * Hopefully, Z/stencil tests culled many of the fragments! + /* If we were able to defer fragment color computation to now, there's + * a good chance that many fragments will have already been killed by + * Z/stencil testing. */ - if (!ctx->Color.AlphaEnabled) { + if (deferredTexture) { /* Now we need the rgba array, fill it in if needed */ if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) interpolate_colors(ctx, span); -- cgit v1.2.3