From 54e92e8420a028f07b0971ee8aa93be9b4214579 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 16 Mar 2003 22:02:36 +0000 Subject: Store partial derivative values in sw_span structure. Implemented DDX and DDY fragment program instructions (whew!) Not fully tested yet. --- src/mesa/swrast/s_context.h | 17 +- src/mesa/swrast/s_nvfragprog.c | 442 +++++++++++++++++++++++++++++++---------- src/mesa/swrast/s_span.c | 4 +- src/mesa/swrast/s_triangle.c | 4 +- src/mesa/swrast/s_tritemp.h | 366 +++++++++++++++++----------------- 5 files changed, 548 insertions(+), 285 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index 91063f0ef8..219e002990 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -1,4 +1,4 @@ -/* $Id: s_context.h,v 1.25 2003/02/28 15:09:02 brianp Exp $ */ +/* $Id: s_context.h,v 1.26 2003/03/16 22:02:36 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -133,6 +133,9 @@ struct sw_span { */ GLuint interpMask; + /* For horizontal spans, step is the partial derivative wrt X. + * For lines, step is the delta from one fragment to the next. + */ #if CHAN_TYPE == GL_FLOAT GLfloat red, redStep; GLfloat green, greenStep; @@ -158,6 +161,18 @@ struct sw_span { GLfloat texStepY[MAX_TEXTURE_COORD_UNITS][4]; GLfixed intTex[2], intTexStep[2]; /* s, t only */ + /* partial derivatives wrt X and Y. */ + GLfloat dzdx, dzdy; + GLfloat w, dwdx, dwdy; + GLfloat drdx, drdy; + GLfloat dgdx, dgdy; + GLfloat dbdx, dbdy; + GLfloat dadx, dady; + GLfloat dsrdx, dsrdy; + GLfloat dsgdx, dsgdy; + GLfloat dsbdx, dsbdy; + GLfloat dfogdx, dfogdy; + /** * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates * which of the fragment arrays in the span_arrays struct are relevant. diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index b139b8cc55..cd3f307f97 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -1,4 +1,4 @@ -/* $Id: s_nvfragprog.c,v 1.8 2003/03/15 17:33:27 brianp Exp $ */ +/* $Id: s_nvfragprog.c,v 1.9 2003/03/16 22:02:37 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -42,7 +42,7 @@ */ static void fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit, - GLuint targetBit, GLfloat color[4] ) + GLfloat color[4] ) { const GLfloat *lambda = NULL; GLchan rgba[4]; @@ -59,12 +59,13 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit, /** - * Fetch a texel w/ partial derivatives. + * Fetch a texel with the given partial derivatives to compute a level + * of detail in the mipmap. */ static void fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], const GLfloat texdx[4], const GLfloat texdy[4], - GLuint unit, GLuint targetBit, GLfloat color[4] ) + GLuint unit, GLfloat color[4] ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; @@ -100,20 +101,131 @@ fetch_vector4( const struct fp_src_register *source, const struct fp_machine *machine, GLfloat result[4] ) { - const GLfloat *src; - - /* - if (source->RelAddr) { - GLint reg = source->Register + machine->AddressReg; - if (reg < VP_PROG_REG_START || reg > VP_PROG_REG_END) - src = zero; - else - src = machine->Registers[reg]; + const GLfloat *src = machine->Registers[source->Register]; + + result[0] = src[source->Swizzle[0]]; + result[1] = src[source->Swizzle[1]]; + result[2] = src[source->Swizzle[2]]; + result[3] = src[source->Swizzle[3]]; + + if (source->NegateBase) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; } - else - */ + if (source->Abs) { + result[0] = FABSF(result[0]); + result[1] = FABSF(result[1]); + result[2] = FABSF(result[2]); + result[3] = FABSF(result[3]); + } + if (source->NegateAbs) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } +} - src = machine->Registers[source->Register]; + +/** + * Fetch the derivative with respect to X for the given register. + * \return GL_TRUE if it was easily computed or GL_FALSE if we + * need to execute another instance of the program (ugh)! + */ +static GLboolean +fetch_vector4_deriv( const struct fp_src_register *source, + const struct sw_span *span, + char xOrY, GLfloat result[4] ) +{ + GLfloat src[4]; + + ASSERT(xOrY == 'X' || xOrY == 'Y'); + + switch (source->Register) { + case FRAG_ATTRIB_WPOS: + if (xOrY == 'X') { + src[0] = 1.0; + src[1] = 0.0; + src[2] = span->dzdx; + src[3] = span->dwdx; + } + else { + src[0] = 0.0; + src[1] = 1.0; + src[2] = span->dzdy; + src[3] = span->dwdy; + } + break; + case FRAG_ATTRIB_COL0: + if (xOrY == 'X') { + src[0] = span->drdx * (1.0F / CHAN_MAXF); + src[1] = span->dgdx * (1.0F / CHAN_MAXF); + src[2] = span->dbdx * (1.0F / CHAN_MAXF); + src[3] = span->dadx * (1.0F / CHAN_MAXF); + } + else { + src[0] = span->drdy * (1.0F / CHAN_MAXF); + src[1] = span->dgdy * (1.0F / CHAN_MAXF); + src[2] = span->dbdy * (1.0F / CHAN_MAXF); + src[3] = span->dady * (1.0F / CHAN_MAXF); + } + break; + case FRAG_ATTRIB_COL1: + if (xOrY == 'X') { + src[0] = span->dsrdx * (1.0F / CHAN_MAXF); + src[1] = span->dsgdx * (1.0F / CHAN_MAXF); + src[2] = span->dsbdx * (1.0F / CHAN_MAXF); + src[3] = 0.0; /* XXX need this */ + } + else { + src[0] = span->dsrdy * (1.0F / CHAN_MAXF); + src[1] = span->dsgdy * (1.0F / CHAN_MAXF); + src[2] = span->dsbdy * (1.0F / CHAN_MAXF); + src[3] = 0.0; /* XXX need this */ + } + break; + case FRAG_ATTRIB_FOGC: + if (xOrY == 'X') { + src[0] = span->dfogdx; + src[1] = 0.0; + src[2] = 0.0; + src[3] = 0.0; + } + else { + src[0] = span->dfogdy; + src[1] = 0.0; + src[2] = 0.0; + src[3] = 0.0; + } + break; + case FRAG_ATTRIB_TEX0: + case FRAG_ATTRIB_TEX1: + case FRAG_ATTRIB_TEX2: + case FRAG_ATTRIB_TEX3: + case FRAG_ATTRIB_TEX4: + case FRAG_ATTRIB_TEX5: + case FRAG_ATTRIB_TEX6: + case FRAG_ATTRIB_TEX7: + if (xOrY == 'X') { + const GLuint u = source->Register - FRAG_ATTRIB_TEX0; + src[0] = span->texStepX[u][0] * (1.0F / CHAN_MAXF); + src[1] = span->texStepX[u][1] * (1.0F / CHAN_MAXF); + src[2] = span->texStepX[u][2] * (1.0F / CHAN_MAXF); + src[3] = span->texStepX[u][3] * (1.0F / CHAN_MAXF); + } + else { + const GLuint u = source->Register - FRAG_ATTRIB_TEX0; + src[0] = span->texStepY[u][0] * (1.0F / CHAN_MAXF); + src[1] = span->texStepY[u][1] * (1.0F / CHAN_MAXF); + src[2] = span->texStepY[u][2] * (1.0F / CHAN_MAXF); + src[3] = span->texStepY[u][3] * (1.0F / CHAN_MAXF); + } + break; + default: + return GL_FALSE; + } result[0] = src[source->Swizzle[0]]; result[1] = src[source->Swizzle[1]]; @@ -138,6 +250,7 @@ fetch_vector4( const struct fp_src_register *source, result[2] = -result[2]; result[3] = -result[3]; } + return GL_TRUE; } @@ -261,19 +374,123 @@ store_vector4( const struct fp_instruction *inst, } +/** + * Initialize a new machine state instance from an existing one, adding + * the partial derivatives onto the input registers. + * Used to implement DDX and DDY instructions in non-trivial cases. + */ +static void +init_machine_deriv( GLcontext *ctx, + const struct fp_machine *machine, + const struct fragment_program *program, + const struct sw_span *span, char xOrY, + struct fp_machine *dMachine ) +{ + GLuint u; + + ASSERT(xOrY == 'X' || xOrY == 'Y'); + + /* copy existing machine */ + _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); + + /* Clear temporary registers */ + _mesa_bzero(machine->Registers + FP_TEMP_REG_START, + MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); + + /* Add derivatives */ + if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) { + GLfloat *wpos = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_WPOS]; + if (xOrY == 'X') { + wpos[0] += 1.0F; + wpos[1] += 0.0F; + wpos[2] += span->dzdx; + wpos[3] += span->dwdx; + } + else { + wpos[0] += 0.0F; + wpos[1] += 1.0F; + wpos[2] += span->dzdy; + wpos[3] += span->dwdy; + } + } + if (program->InputsRead & (1 << FRAG_ATTRIB_COL0)) { + GLfloat *col0 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL0]; + if (xOrY == 'X') { + col0[0] += span->drdx * (1.0F / CHAN_MAXF); + col0[1] += span->dgdx * (1.0F / CHAN_MAXF); + col0[2] += span->dbdx * (1.0F / CHAN_MAXF); + col0[3] += span->dadx * (1.0F / CHAN_MAXF); + } + else { + col0[0] += span->drdy * (1.0F / CHAN_MAXF); + col0[1] += span->dgdy * (1.0F / CHAN_MAXF); + col0[2] += span->dbdy * (1.0F / CHAN_MAXF); + col0[3] += span->dady * (1.0F / CHAN_MAXF); + } + } + if (program->InputsRead & (1 << FRAG_ATTRIB_COL1)) { + GLfloat *col1 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL1]; + if (xOrY == 'X') { + col1[0] += span->dsrdx * (1.0F / CHAN_MAXF); + col1[1] += span->dsgdx * (1.0F / CHAN_MAXF); + col1[2] += span->dsbdx * (1.0F / CHAN_MAXF); + col1[3] += 0.0; /*XXX fix */ + } + else { + col1[0] += span->dsrdy * (1.0F / CHAN_MAXF); + col1[1] += span->dsgdy * (1.0F / CHAN_MAXF); + col1[2] += span->dsbdy * (1.0F / CHAN_MAXF); + col1[3] += 0.0; /*XXX fix */ + } + } + if (program->InputsRead & (1 << FRAG_ATTRIB_FOGC)) { + GLfloat *fogc = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_FOGC]; + if (xOrY == 'X') { + fogc[0] += span->dfogdx; + } + else { + fogc[0] += span->dfogdy; + } + } + for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { + if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { + GLfloat *tex = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_TEX0+u]; + if (xOrY == 'X') { + tex[0] += span->texStepX[u][0]; + tex[1] += span->texStepX[u][1]; + tex[2] += span->texStepX[u][2]; + tex[3] += span->texStepX[u][3]; + } + else { + tex[0] += span->texStepY[u][0]; + tex[1] += span->texStepY[u][1]; + tex[2] += span->texStepY[u][2]; + tex[3] += span->texStepY[u][3]; + } + } + } +} + + /** * Execute the given vertex program. * NOTE: we do everything in single-precision floating point; we don't * currently observe the single/half/fixed-precision qualifiers. + * \param ctx - rendering context + * \param program - the fragment program to execute + * \param machine - machine state (register file) + * \param maxInst - max number of instructions to execute * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. */ static GLboolean -execute_program(GLcontext *ctx, const struct fragment_program *program) +execute_program( GLcontext *ctx, + const struct fragment_program *program, GLuint maxInst, + struct fp_machine *machine, const struct sw_span *span ) { - struct fp_machine *machine = &ctx->FragmentProgram.Machine; - const struct fp_instruction *inst; + GLuint pc = 0; - for (inst = program->Instructions; inst->Opcode != FP_OPCODE_END; inst++) { + for (pc = 0; pc < maxInst; pc++) { + const struct fp_instruction *inst = program->Instructions + pc; switch (inst->Opcode) { case FP_OPCODE_ADD: { @@ -297,32 +514,42 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) break; case FP_OPCODE_DDX: /* Partial derivative with respect to X */ { - GLfloat a[4], result[4]; - fetch_vector4( &inst->SrcReg[0], machine, a ); - /* XXX - UGH! this is going to be a mess to implement! - * If we need the partial derivative of a texture coord - * or color, that's not too bad, but for an arbitrary register - * this will require a recursive solution. That is, we'll have - * to run another instance of this program with WPOS.x or .y - * incremented by one, stopping at the preceeding instruction. - * Then, read the register from that other instance and compute - * the difference. Yuck! - */ - result[0] = 0; /* XXX fix */ - result[1] = 0; - result[2] = 0; - result[3] = 0; + GLfloat a[4], aNext[4], result[4]; + struct fp_machine dMachine; + if (!fetch_vector4_deriv(&inst->SrcReg[0], span, 'X', result)) { + /* This is tricky. Make a copy of the current machine state, + * increment the input registers by the dx or dy partial + * derivatives, then re-execute the program up to the + * preceeding instruction, then fetch the source register. + * Finally, find the difference in the register values for + * the original and derivative runs. + */ + init_machine_deriv(ctx, machine, program, span, + 'X', &dMachine); + execute_program(ctx, program, pc, &dMachine, span); + fetch_vector4( &inst->SrcReg[0], &dMachine, aNext ); + result[0] = aNext[0] - a[0]; + result[1] = aNext[1] - a[1]; + result[2] = aNext[2] - a[2]; + result[3] = aNext[3] - a[3]; + } store_vector4( inst, machine, result ); } break; case FP_OPCODE_DDY: /* Partial derivative with respect to Y */ { - GLfloat a[4], result[4]; - fetch_vector4( &inst->SrcReg[0], machine, a ); - result[0] = 0; /* XXX fix */ - result[1] = 0; - result[2] = 0; - result[3] = 0; + GLfloat a[4], aNext[4], result[4]; + struct fp_machine dMachine; + if (!fetch_vector4_deriv(&inst->SrcReg[0], span, 'Y', result)) { + init_machine_deriv(ctx, machine, program, span, + 'Y', &dMachine); + execute_program(ctx, program, pc, &dMachine, span); + fetch_vector4( &inst->SrcReg[0], &dMachine, aNext ); + result[0] = aNext[0] - a[0]; + result[1] = aNext[1] - a[1]; + result[2] = aNext[2] - a[2]; + result[3] = aNext[3] - a[3]; + } store_vector4( inst, machine, result ); } break; @@ -710,8 +937,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) GLfloat texcoord[4], color[4]; fetch_vector4( &inst->SrcReg[0], machine, texcoord ); /* XXX: Undo perspective divide from interpolate_texcoords() */ - fetch_texel( ctx, texcoord, inst->TexSrcUnit, - inst->TexSrcBit, color ); + fetch_texel( ctx, texcoord, inst->TexSrcUnit, color ); store_vector4( inst, machine, color ); } break; @@ -723,7 +949,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) fetch_vector4( &inst->SrcReg[1], machine, dtdx ); fetch_vector4( &inst->SrcReg[2], machine, dtdy ); fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit, - inst->TexSrcBit, color ); + color ); store_vector4( inst, machine, color ); } break; @@ -733,8 +959,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) GLfloat texcoord[4], color[4]; fetch_vector4( &inst->SrcReg[0], machine, texcoord ); /* Already did perspective divide in interpolate_texcoords() */ - fetch_texel( ctx, texcoord, inst->TexSrcUnit, - inst->TexSrcBit, color ); + fetch_texel( ctx, texcoord, inst->TexSrcUnit, color ); store_vector4( inst, machine, color ); } break; @@ -801,8 +1026,11 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) store_vector4( inst, machine, result ); } break; + case FP_OPCODE_END: + return GL_TRUE; default: - _mesa_problem(ctx, "Bad opcode in _mesa_exec_fragment_program"); + _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program", + inst->Opcode); return GL_TRUE; /* return value doesn't matter */ } } @@ -810,6 +1038,59 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) } +static void +init_machine( GLcontext *ctx, struct fp_machine *machine, + const struct fragment_program *program, + const struct sw_span *span, GLuint i ) +{ + GLuint u; + + /* Clear temporary registers */ + _mesa_bzero(machine->Registers + FP_TEMP_REG_START, + MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); + + /* Load input registers */ + if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) { + GLfloat *wpos = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_WPOS]; + wpos[0] = span->x + i; + wpos[1] = span->y + i; + wpos[2] = (GLfloat) span->array->z[i] / ctx->DepthMaxF; + wpos[3] = span->w + i * span->dwdx; + } + if (program->InputsRead & (1 << FRAG_ATTRIB_COL0)) { + GLfloat *col0 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL0]; + col0[0] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]); + col0[1] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); + col0[2] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); + col0[3] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]); + } + if (program->InputsRead & (1 << FRAG_ATTRIB_COL1)) { + GLfloat *col1 = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_COL1]; + col1[0] = CHAN_TO_FLOAT(span->array->spec[i][RCOMP]); + col1[1] = CHAN_TO_FLOAT(span->array->spec[i][GCOMP]); + col1[2] = CHAN_TO_FLOAT(span->array->spec[i][BCOMP]); + col1[3] = CHAN_TO_FLOAT(span->array->spec[i][ACOMP]); + } + if (program->InputsRead & (1 << FRAG_ATTRIB_FOGC)) { + GLfloat *fogc = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_FOGC]; + fogc[0] = span->array->fog[i]; + fogc[1] = 0.0F; + fogc[2] = 0.0F; + fogc[3] = 0.0F; + } + for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { + if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { + GLfloat *tex = machine->Registers[FP_INPUT_REG_START+FRAG_ATTRIB_TEX0+u]; + if (ctx->Texture.Unit[u]._ReallyEnabled) { + COPY_4V(tex, span->array->texcoords[u][i]); + } + else { + COPY_4V(tex, ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]); + } + } + } +} + void _swrast_exec_nv_fragment_program( GLcontext *ctx, struct sw_span *span ) @@ -819,65 +1100,22 @@ _swrast_exec_nv_fragment_program( GLcontext *ctx, struct sw_span *span ) for (i = 0; i < span->end; i++) { if (span->array->mask[i]) { - const GLfloat *colOut = ctx->FragmentProgram.Machine.Registers[FP_OUTPUT_REG_START]; - GLuint u; - - /* Clear temporary registers */ - _mesa_bzero(ctx->FragmentProgram.Machine.Registers +FP_TEMP_REG_START, - MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); - - /* - * Load input registers - yes this is all very inefficient for now. - */ - if (program->InputsRead & (1 << FRAG_ATTRIB_WPOS)) { - GLfloat *wpos = ctx->FragmentProgram.Machine.Registers[0]; - wpos[0] = span->x + i; - wpos[1] = span->y + i; - wpos[2] = (GLfloat) span->array->z[i] / ctx->DepthMaxF; - wpos[3] = 1.0; /* XXX should be 1/w */ - } - if (program->InputsRead & (1 << FRAG_ATTRIB_COL0)) { - GLfloat *col0 = ctx->FragmentProgram.Machine.Registers[1]; - col0[0] = CHAN_TO_FLOAT(span->array->rgba[i][RCOMP]); - col0[1] = CHAN_TO_FLOAT(span->array->rgba[i][GCOMP]); - col0[2] = CHAN_TO_FLOAT(span->array->rgba[i][BCOMP]); - col0[3] = CHAN_TO_FLOAT(span->array->rgba[i][ACOMP]); - } - if (program->InputsRead & (1 << FRAG_ATTRIB_COL1)) { - GLfloat *col1 = ctx->FragmentProgram.Machine.Registers[2]; - col1[0] = CHAN_TO_FLOAT(span->array->spec[i][RCOMP]); - col1[1] = CHAN_TO_FLOAT(span->array->spec[i][GCOMP]); - col1[2] = CHAN_TO_FLOAT(span->array->spec[i][BCOMP]); - col1[3] = CHAN_TO_FLOAT(span->array->spec[i][ACOMP]); - } - if (program->InputsRead & (1 << FRAG_ATTRIB_FOGC)) { - GLfloat *fogc = ctx->FragmentProgram.Machine.Registers[3]; - fogc[0] = span->array->fog[i]; - fogc[1] = 0.0F; - fogc[2] = 0.0F; - fogc[3] = 0.0F; - } - for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (program->InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + u], - span->array->texcoords[u][i]); - } - else { - COPY_4V(ctx->FragmentProgram.Machine.Registers[4 + u], - ctx->Current.Attrib[VERT_ATTRIB_TEX0 + u]); - } - } - } + init_machine(ctx, &ctx->FragmentProgram.Machine, + ctx->FragmentProgram.Current, span, i); - if (!execute_program(ctx, program)) + if (!execute_program(ctx, program, ~0, + &ctx->FragmentProgram.Machine, span)) span->array->mask[i] = GL_FALSE; /* killed fragment */ /* Store output registers */ - UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][RCOMP], colOut[0]); - UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][GCOMP], colOut[1]); - UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][BCOMP], colOut[2]); - UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], colOut[3]); + { + const GLfloat *colOut + = ctx->FragmentProgram.Machine.Registers[FP_OUTPUT_REG_START]; + UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][RCOMP], colOut[0]); + UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][GCOMP], colOut[1]); + UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][BCOMP], colOut[2]); + UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], colOut[3]); + } /* depth value */ if (ctx->FragmentProgram.Current->OutputsWritten & 2) span->array->z[i] = IROUND(ctx->FragmentProgram.Machine.Registers[FP_OUTPUT_REG_START + 2][0] * ctx->DepthMaxF); diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index cb02ab924d..842f3be3c2 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1,4 +1,4 @@ -/* $Id: s_span.c,v 1.58 2003/03/15 17:33:27 brianp Exp $ */ +/* $Id: s_span.c,v 1.59 2003/03/16 22:02:37 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -76,7 +76,7 @@ void _mesa_span_default_fog( GLcontext *ctx, struct sw_span *span ) { span->fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance); - span->fogStep = 0; + span->fogStep = span->dfogdx = span->dfogdy = 0.0F; span->interpMask |= SPAN_FOG; } diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index 538102f41f..fce782466f 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -1,4 +1,4 @@ -/* $Id: s_triangle.c,v 1.68 2003/03/14 15:41:00 brianp Exp $ */ +/* $Id: s_triangle.c,v 1.69 2003/03/16 22:02:38 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -870,6 +870,7 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span, */ #define NAME general_textured_triangle #define INTERP_Z 1 +#define INTERP_W 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 @@ -888,6 +889,7 @@ fast_persp_span(GLcontext *ctx, struct sw_span *span, */ #define NAME multitextured_triangle #define INTERP_Z 1 +#define INTERP_W 1 #define INTERP_FOG 1 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE #define INTERP_RGB 1 diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 37d17d4bc8..b5273500ce 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -1,4 +1,4 @@ -/* $Id: s_tritemp.h,v 1.46 2003/03/16 20:10:01 brianp Exp $ */ +/* $Id: s_tritemp.h,v 1.47 2003/03/16 22:02:40 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -301,25 +301,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { GLint scan_from_left_to_right; /* true if scanning left-to-right */ -#ifdef INTERP_Z - GLfloat dzdx, dzdy; -#endif -#ifdef INTERP_FOG - GLfloat dfogdy; -#endif -#if defined(INTERP_RGB) - GLfloat drdx, drdy; - GLfloat dgdx, dgdy; - GLfloat dbdx, dbdy; -#endif -#if defined(INTERP_ALPHA) - GLfloat dadx, dady; -#endif -#if defined(INTERP_SPEC) - GLfloat dsrdx, dsrdy; - GLfloat dsgdx, dsgdy; - GLfloat dsbdx, dsbdy; -#endif #ifdef INTERP_INDEX GLfloat didx, didy; #endif @@ -338,22 +319,29 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_Z span.interpMask |= SPAN_Z; { - GLfloat eMaj_dz, eBot_dz; - eMaj_dz = vMax->win[2] - vMin->win[2]; - eBot_dz = vMid->win[2] - vMin->win[2]; - dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); - if (dzdx > maxDepth || dzdx < -maxDepth) { + GLfloat eMaj_dz = vMax->win[2] - vMin->win[2]; + GLfloat eBot_dz = vMid->win[2] - vMin->win[2]; + span.dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); + if (span.dzdx > maxDepth || span.dzdx < -maxDepth) { /* probably a sliver triangle */ - dzdx = 0.0; - dzdy = 0.0; + span.dzdx = 0.0; + span.dzdy = 0.0; } else { - dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); + span.dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); } if (depthBits <= 16) - span.zStep = SignedFloatToFixed(dzdx); + span.zStep = SignedFloatToFixed(span.dzdx); else - span.zStep = (GLint) dzdx; + span.zStep = (GLint) span.dzdx; + } +#endif +#ifdef INTERP_W + { + const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3]; + const GLfloat eBot_dw = vMid->win[3] - vMin->win[3]; + span.dwdx = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); + span.dwdy = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); } #endif #ifdef INTERP_FOG @@ -361,8 +349,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { const GLfloat eMaj_dfog = vMax->fog - vMin->fog; const GLfloat eBot_dfog = vMid->fog - vMin->fog; - span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); - dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); + span.dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); + span.dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); + span.fogStep = span.dfogdx; } #endif #ifdef INTERP_RGB @@ -378,39 +367,39 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - vMin->color[ACOMP]); GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - vMin->color[ACOMP]); # endif - drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); - drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); - dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); - dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); - dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); - dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); + span.drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); + span.drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); + span.dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); + span.dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); + span.dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); + span.dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.redStep = drdx; - span.greenStep = dgdx; - span.blueStep = dbdx; + span.redStep = span.drdx; + span.greenStep = span.dgdx; + span.blueStep = span.dbdx; # else - span.redStep = SignedFloatToFixed(drdx); - span.greenStep = SignedFloatToFixed(dgdx); - span.blueStep = SignedFloatToFixed(dbdx); + span.redStep = SignedFloatToFixed(span.drdx); + span.greenStep = SignedFloatToFixed(span.dgdx); + span.blueStep = SignedFloatToFixed(span.dbdx); # endif /* GL_FLOAT */ # ifdef INTERP_ALPHA - dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); - dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + span.dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.alphaStep = dadx; + span.alphaStep = span.dadx; # else - span.alphaStep = SignedFloatToFixed(dadx); + span.alphaStep = SignedFloatToFixed(span.dadx); # endif /* GL_FLOAT */ # endif /* INTERP_ALPHA */ } else { ASSERT (ctx->Light.ShadeModel == GL_FLAT); span.interpMask |= SPAN_FLAT; - drdx = drdy = span.redStep = 0; - dgdx = dgdy = span.greenStep = 0; - dbdx = dbdy = span.blueStep = 0; + span.drdx = span.drdy = span.redStep = 0; + span.dgdx = span.dgdy = span.greenStep = 0; + span.dbdx = span.dbdy = span.blueStep = 0; # ifdef INTERP_ALPHA - dadx = dady = span.alphaStep = 0; + span.dadx = span.dady = span.alphaStep = 0; # endif } #endif /* INTERP_RGB */ @@ -423,26 +412,26 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - vMin->specular[GCOMP]); GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - vMin->specular[BCOMP]); GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - vMin->specular[BCOMP]); - dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); - dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); - dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); - dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); - dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); - dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); + span.dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); + span.dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); + span.dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); + span.dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); + span.dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); + span.dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.specRedStep = dsrdx; - span.specGreenStep = dsgdx; - span.specBlueStep = dsbdx; + span.specRedStep = span.dsrdx; + span.specGreenStep = span.dsgdx; + span.specBlueStep = span.dsbdx; # else - span.specRedStep = SignedFloatToFixed(dsrdx); - span.specGreenStep = SignedFloatToFixed(dsgdx); - span.specBlueStep = SignedFloatToFixed(dsbdx); + span.specRedStep = SignedFloatToFixed(span.dsrdx); + span.specGreenStep = SignedFloatToFixed(span.dsgdx); + span.specBlueStep = SignedFloatToFixed(span.dsbdx); # endif } else { - dsrdx = dsrdy = span.specRedStep = 0; - dsgdx = dsgdy = span.specGreenStep = 0; - dsbdx = dsbdy = span.specBlueStep = 0; + span.dsrdx = span.dsrdy = span.specRedStep = 0; + span.dsgdx = span.dsgdy = span.specGreenStep = 0; + span.dsbdx = span.dsbdy = span.specBlueStep = 0; } #endif /* INTERP_SPEC */ #ifdef INTERP_INDEX @@ -568,30 +557,33 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, DEPTH_TYPE *zRow = NULL; int dZRowOuter = 0, dZRowInner; /* offset in bytes */ # endif - GLfixed fz = 0, fdzOuter = 0, fdzInner; + GLfixed zLeft = 0, fdzOuter = 0, fdzInner; +#endif +#ifdef INTERP_W + GLfloat wLeft, dwOuter, dwInner; #endif #ifdef INTERP_FOG GLfloat fogLeft = 0, dfogOuter = 0, dfogInner; #endif #ifdef INTERP_RGB - ColorTemp fr = 0, fdrOuter = 0, fdrInner; - ColorTemp fg = 0, fdgOuter = 0, fdgInner; - ColorTemp fb = 0, fdbOuter = 0, fdbInner; + ColorTemp rLeft = 0, fdrOuter = 0, fdrInner; + ColorTemp gLeft = 0, fdgOuter = 0, fdgInner; + ColorTemp bLeft = 0, fdbOuter = 0, fdbInner; #endif #ifdef INTERP_ALPHA - ColorTemp fa = 0, fdaOuter = 0, fdaInner; + ColorTemp aLeft = 0, fdaOuter = 0, fdaInner; #endif #ifdef INTERP_SPEC - ColorTemp fsr=0, fdsrOuter=0, fdsrInner; - ColorTemp fsg=0, fdsgOuter=0, fdsgInner; - ColorTemp fsb=0, fdsbOuter=0, fdsbInner; + ColorTemp srLeft=0, dsrOuter=0, dsrInner; + ColorTemp sgLeft=0, dsgOuter=0, dsgInner; + ColorTemp sbLeft=0, dsbOuter=0, dsbInner; #endif #ifdef INTERP_INDEX - GLfixed fi=0, fdiOuter=0, fdiInner; + GLfixed iLeft=0, diOuter=0, diInner; #endif #ifdef INTERP_INT_TEX - GLfixed fs=0, fdsOuter=0, fdsInner; - GLfixed ft=0, fdtOuter=0, fdtInner; + GLfixed sLeft=0, dsOuter=0, dsInner; + GLfixed tLeft=0, dtOuter=0, dtInner; #endif #ifdef INTERP_TEX GLfloat sLeft[MAX_TEXTURE_COORD_UNITS]; @@ -695,17 +687,17 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat z0 = vLower->win[2]; if (depthBits <= 16) { /* interpolate fixed-pt values */ - GLfloat tmp = (z0 * FIXED_SCALE + dzdx * adjx + dzdy * adjy) + FIXED_HALF; + GLfloat tmp = (z0 * FIXED_SCALE + span.dzdx * adjx + span.dzdy * adjy) + FIXED_HALF; if (tmp < MAX_GLUINT / 2) - fz = (GLfixed) tmp; + zLeft = (GLfixed) tmp; else - fz = MAX_GLUINT / 2; - fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx); + zLeft = MAX_GLUINT / 2; + fdzOuter = SignedFloatToFixed(span.dzdy + dxOuter * span.dzdx); } else { /* interpolate depth values exactly */ - fz = (GLint) (z0 + dzdx * FixedToFloat(adjx) + dzdy * FixedToFloat(adjy)); - fdzOuter = (GLint) (dzdy + dxOuter * dzdx); + zLeft = (GLint) (z0 + span.dzdx * FixedToFloat(adjx) + span.dzdy * FixedToFloat(adjy)); + fdzOuter = (GLint) (span.dzdy + dxOuter * span.dzdx); } # ifdef DEPTH_TYPE zRow = (DEPTH_TYPE *) @@ -714,57 +706,60 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif } #endif +#ifdef INTERP_W + wLeft = vLower->win[3] + (span.dwdx * adjx + span.dwdy * adjy) * (1.0F/FIXED_SCALE); + dwOuter = span.dwdy + dxOuter * span.dwdx; +#endif #ifdef INTERP_FOG - fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy) - * (1.0F/FIXED_SCALE); - dfogOuter = dfogdy + dxOuter * span.fogStep; + fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE); + dfogOuter = span.dfogdy + dxOuter * span.dfogdx; #endif #ifdef INTERP_RGB if (ctx->Light.ShadeModel == GL_SMOOTH) { # if CHAN_TYPE == GL_FLOAT - fr = vLower->color[RCOMP] + (drdx * adjx + drdy * adjy) * (1.0F / FIXED_SCALE); - fg = vLower->color[GCOMP] + (dgdx * adjx + dgdy * adjy) * (1.0F / FIXED_SCALE); - fb = vLower->color[BCOMP] + (dbdx * adjx + dbdy * adjy) * (1.0F / FIXED_SCALE); - fdrOuter = drdy + dxOuter * drdx; - fdgOuter = dgdy + dxOuter * dgdx; - fdbOuter = dbdy + dxOuter * dbdx; + rLeft = vLower->color[RCOMP] + (span.drdx * adjx + span.drdy * adjy) * (1.0F / FIXED_SCALE); + gLeft = vLower->color[GCOMP] + (span.dgdx * adjx + span.dgdy * adjy) * (1.0F / FIXED_SCALE); + bLeft = vLower->color[BCOMP] + (span.dbdx * adjx + span.dbdy * adjy) * (1.0F / FIXED_SCALE); + fdrOuter = span.drdy + dxOuter * span.drdx; + fdgOuter = span.dgdy + dxOuter * span.dgdx; + fdbOuter = span.dbdy + dxOuter * span.dbdx; # else - fr = (ChanToFixed(vLower->color[RCOMP]) + drdx * adjx + drdy * adjy) + FIXED_HALF; - fg = (ChanToFixed(vLower->color[GCOMP]) + dgdx * adjx + dgdy * adjy) + FIXED_HALF; - fb = (ChanToFixed(vLower->color[BCOMP]) + dbdx * adjx + dbdy * adjy) + FIXED_HALF; - fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx); - fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx); - fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx); + rLeft = (ChanToFixed(vLower->color[RCOMP]) + span.drdx * adjx + span.drdy * adjy) + FIXED_HALF; + gLeft = (ChanToFixed(vLower->color[GCOMP]) + span.dgdx * adjx + span.dgdy * adjy) + FIXED_HALF; + bLeft = (ChanToFixed(vLower->color[BCOMP]) + span.dbdx * adjx + span.dbdy * adjy) + FIXED_HALF; + fdrOuter = SignedFloatToFixed(span.drdy + dxOuter * span.drdx); + fdgOuter = SignedFloatToFixed(span.dgdy + dxOuter * span.dgdx); + fdbOuter = SignedFloatToFixed(span.dbdy + dxOuter * span.dbdx); # endif # ifdef INTERP_ALPHA # if CHAN_TYPE == GL_FLOAT - fa = vLower->color[ACOMP] + (dadx * adjx + dady * adjy) * (1.0F / FIXED_SCALE); - fdaOuter = dady + dxOuter * dadx; + aLeft = vLower->color[ACOMP] + (span.dadx * adjx + span.dady * adjy) * (1.0F / FIXED_SCALE); + fdaOuter = span.dady + dxOuter * span.dadx; # else - fa = (ChanToFixed(vLower->color[ACOMP]) + dadx * adjx + dady * adjy) + FIXED_HALF; - fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx); + aLeft = (ChanToFixed(vLower->color[ACOMP]) + span.dadx * adjx + span.dady * adjy) + FIXED_HALF; + fdaOuter = SignedFloatToFixed(span.dady + dxOuter * span.dadx); # endif # endif } else { ASSERT (ctx->Light.ShadeModel == GL_FLAT); # if CHAN_TYPE == GL_FLOAT - fr = v2->color[RCOMP]; - fg = v2->color[GCOMP]; - fb = v2->color[BCOMP]; + rLeft = v2->color[RCOMP]; + gLeft = v2->color[GCOMP]; + bLeft = v2->color[BCOMP]; fdrOuter = fdgOuter = fdbOuter = 0.0F; # else - fr = ChanToFixed(v2->color[RCOMP]); - fg = ChanToFixed(v2->color[GCOMP]); - fb = ChanToFixed(v2->color[BCOMP]); + rLeft = ChanToFixed(v2->color[RCOMP]); + gLeft = ChanToFixed(v2->color[GCOMP]); + bLeft = ChanToFixed(v2->color[BCOMP]); fdrOuter = fdgOuter = fdbOuter = 0; # endif # ifdef INTERP_ALPHA # if CHAN_TYPE == GL_FLOAT - fa = v2->color[ACOMP]; + aLeft = v2->color[ACOMP]; fdaOuter = 0.0F; # else - fa = ChanToFixed(v2->color[ACOMP]); + aLeft = ChanToFixed(v2->color[ACOMP]); fdaOuter = 0; # endif # endif @@ -774,59 +769,59 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_SPEC if (ctx->Light.ShadeModel == GL_SMOOTH) { # if CHAN_TYPE == GL_FLOAT - fsr = vLower->specular[RCOMP] + (dsrdx * adjx + dsrdy * adjy) * (1.0F / FIXED_SCALE); - fsg = vLower->specular[GCOMP] + (dsgdx * adjx + dsgdy * adjy) * (1.0F / FIXED_SCALE); - fsb = vLower->specular[BCOMP] + (dsbdx * adjx + dsbdy * adjy) * (1.0F / FIXED_SCALE); - fdsrOuter = dsrdy + dxOuter * dsrdx; - fdsgOuter = dsgdy + dxOuter * dsgdx; - fdsbOuter = dsbdy + dxOuter * dsbdx; + srLeft = vLower->specular[RCOMP] + (span.dsrdx * adjx + span.dsrdy * adjy) * (1.0F / FIXED_SCALE); + sgLeft = vLower->specular[GCOMP] + (span.dsgdx * adjx + span.dsgdy * adjy) * (1.0F / FIXED_SCALE); + sbLeft = vLower->specular[BCOMP] + (span.dsbdx * adjx + span.dsbdy * adjy) * (1.0F / FIXED_SCALE); + dsrOuter = span.dsrdy + dxOuter * span.dsrdx; + dsgOuter = span.dsgdy + dxOuter * span.dsgdx; + dsbOuter = span.dsbdy + dxOuter * span.dsbdx; # else - fsr = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + dsrdx * adjx + dsrdy * adjy) + FIXED_HALF; - fsg = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + dsgdx * adjx + dsgdy * adjy) + FIXED_HALF; - fsb = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + dsbdx * adjx + dsbdy * adjy) + FIXED_HALF; - fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx); - fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx); - fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx); + srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.dsrdx * adjx + span.dsrdy * adjy) + FIXED_HALF; + sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.dsgdx * adjx + span.dsgdy * adjy) + FIXED_HALF; + sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.dsbdx * adjx + span.dsbdy * adjy) + FIXED_HALF; + dsrOuter = SignedFloatToFixed(span.dsrdy + dxOuter * span.dsrdx); + dsgOuter = SignedFloatToFixed(span.dsgdy + dxOuter * span.dsgdx); + dsbOuter = SignedFloatToFixed(span.dsbdy + dxOuter * span.dsbdx); # endif } else { #if CHAN_TYPE == GL_FLOAT - fsr = v2->specular[RCOMP]; - fsg = v2->specular[GCOMP]; - fsb = v2->specular[BCOMP]; - fdsrOuter = fdsgOuter = fdsbOuter = 0.0F; + srLeft = v2->specular[RCOMP]; + sgLeft = v2->specular[GCOMP]; + sbLeft = v2->specular[BCOMP]; + dsrOuter = dsgOuter = dsbOuter = 0.0F; # else - fsr = ChanToFixed(v2->specular[RCOMP]); - fsg = ChanToFixed(v2->specular[GCOMP]); - fsb = ChanToFixed(v2->specular[BCOMP]); - fdsrOuter = fdsgOuter = fdsbOuter = 0; + srLeft = ChanToFixed(v2->specular[RCOMP]); + sgLeft = ChanToFixed(v2->specular[GCOMP]); + sbLeft = ChanToFixed(v2->specular[BCOMP]); + dsrOuter = dsgOuter = dsbOuter = 0; # endif } #endif #ifdef INTERP_INDEX if (ctx->Light.ShadeModel == GL_SMOOTH) { - fi = (GLfixed)(vLower->index * FIXED_SCALE + iLeft = (GLfixed)(vLower->index * FIXED_SCALE + didx * adjx + didy * adjy) + FIXED_HALF; - fdiOuter = SignedFloatToFixed(didy + dxOuter * didx); + diOuter = SignedFloatToFixed(didy + dxOuter * didx); } else { - fi = (GLfixed) (v2->index * FIXED_SCALE); - fdiOuter = 0; + iLeft = (GLfixed) (v2->index * FIXED_SCALE); + diOuter = 0; } #endif #ifdef INTERP_INT_TEX { GLfloat s0, t0; s0 = vLower->texcoord[0][0] * S_SCALE; - fs = (GLfixed)(s0 * FIXED_SCALE + span.texStepX[0][0] * adjx + sLeft = (GLfixed)(s0 * FIXED_SCALE + span.texStepX[0][0] * adjx + span.texStepY[0][0] * adjy) + FIXED_HALF; - fdsOuter = SignedFloatToFixed(span.texStepY[0][0] + dxOuter * span.texStepX[0][0]); + dsOuter = SignedFloatToFixed(span.texStepY[0][0] + dxOuter * span.texStepX[0][0]); t0 = vLower->texcoord[0][1] * T_SCALE; - ft = (GLfixed)(t0 * FIXED_SCALE + span.texStepX[0][1] * adjx + tLeft = (GLfixed)(t0 * FIXED_SCALE + span.texStepX[0][1] * adjx + span.texStepY[0][1] * adjy) + FIXED_HALF; - fdtOuter = SignedFloatToFixed(span.texStepY[0][1] + dxOuter * span.texStepX[0][1]); + dtOuter = SignedFloatToFixed(span.texStepY[0][1] + dxOuter * span.texStepX[0][1]); } #endif #ifdef INTERP_TEX @@ -869,8 +864,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif fdzInner = fdzOuter + span.zStep; #endif +#ifdef INTERP_W + dwInner = dwOuter + span.dwdx; +#endif #ifdef INTERP_FOG - dfogInner = dfogOuter + span.fogStep; + dfogInner = dfogOuter + span.dfogdx; #endif #if defined(INTERP_RGB) fdrInner = fdrOuter + span.redStep; @@ -881,16 +879,16 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, fdaInner = fdaOuter + span.alphaStep; #endif #if defined(INTERP_SPEC) - fdsrInner = fdsrOuter + span.specRedStep; - fdsgInner = fdsgOuter + span.specGreenStep; - fdsbInner = fdsbOuter + span.specBlueStep; + dsrInner = dsrOuter + span.specRedStep; + dsgInner = dsgOuter + span.specGreenStep; + dsbInner = dsbOuter + span.specBlueStep; #endif #ifdef INTERP_INDEX - fdiInner = fdiOuter + span.indexStep; + diInner = diOuter + span.indexStep; #endif #ifdef INTERP_INT_TEX - fdsInner = fdsOuter + span.intTexStep[0]; - fdtInner = fdtOuter + span.intTexStep[1]; + dsInner = dsOuter + span.intTexStep[0]; + dtInner = dtOuter + span.intTexStep[1]; #endif #ifdef INTERP_TEX TEX_UNIT_LOOP( @@ -914,30 +912,33 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.end = right - span.x; #ifdef INTERP_Z - span.z = fz; + span.z = zLeft; +#endif +#ifdef INTERP_W + span.w = wLeft; #endif #ifdef INTERP_FOG span.fog = fogLeft; #endif #if defined(INTERP_RGB) - span.red = fr; - span.green = fg; - span.blue = fb; + span.red = rLeft; + span.green = gLeft; + span.blue = bLeft; #endif #if defined(INTERP_ALPHA) - span.alpha = fa; + span.alpha = aLeft; #endif #if defined(INTERP_SPEC) - span.specRed = fsr; - span.specGreen = fsg; - span.specBlue = fsb; + span.specRed = srLeft; + span.specGreen = sgLeft; + span.specBlue = sbLeft; #endif #ifdef INTERP_INDEX - span.index = fi; + span.index = iLeft; #endif #ifdef INTERP_INT_TEX - span.intTex[0] = fs; - span.intTex[1] = ft; + span.intTex[0] = sLeft; + span.intTex[1] = tLeft; #endif #ifdef INTERP_TEX @@ -1040,30 +1041,33 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # ifdef DEPTH_TYPE zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter); # endif - fz += fdzOuter; + zLeft += fdzOuter; +#endif +#ifdef INTERP_W + wLeft += dwOuter; #endif #ifdef INTERP_FOG fogLeft += dfogOuter; #endif #if defined(INTERP_RGB) - fr += fdrOuter; - fg += fdgOuter; - fb += fdbOuter; + rLeft += fdrOuter; + gLeft += fdgOuter; + bLeft += fdbOuter; #endif #if defined(INTERP_ALPHA) - fa += fdaOuter; + aLeft += fdaOuter; #endif #if defined(INTERP_SPEC) - fsr += fdsrOuter; - fsg += fdsgOuter; - fsb += fdsbOuter; + srLeft += dsrOuter; + sgLeft += dsgOuter; + sbLeft += dsbOuter; #endif #ifdef INTERP_INDEX - fi += fdiOuter; + iLeft += diOuter; #endif #ifdef INTERP_INT_TEX - fs += fdsOuter; - ft += fdtOuter; + sLeft += dsOuter; + tLeft += dtOuter; #endif #ifdef INTERP_TEX TEX_UNIT_LOOP( @@ -1082,30 +1086,33 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # ifdef DEPTH_TYPE zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner); # endif - fz += fdzInner; + zLeft += fdzInner; +#endif +#ifdef INTERP_W + wLeft += dwInner; #endif #ifdef INTERP_FOG fogLeft += dfogInner; #endif #if defined(INTERP_RGB) - fr += fdrInner; - fg += fdgInner; - fb += fdbInner; + rLeft += fdrInner; + gLeft += fdgInner; + bLeft += fdbInner; #endif #if defined(INTERP_ALPHA) - fa += fdaInner; + aLeft += fdaInner; #endif #if defined(INTERP_SPEC) - fsr += fdsrInner; - fsg += fdsgInner; - fsb += fdsbInner; + srLeft += dsrInner; + sgLeft += dsgInner; + sbLeft += dsbInner; #endif #ifdef INTERP_INDEX - fi += fdiInner; + iLeft += diInner; #endif #ifdef INTERP_INT_TEX - fs += fdsInner; - ft += fdtInner; + sLeft += dsInner; + tLeft += dtInner; #endif #ifdef INTERP_TEX TEX_UNIT_LOOP( @@ -1136,6 +1143,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #undef PIXEL_ADDRESS #undef INTERP_Z +#undef INTERP_W #undef INTERP_FOG #undef INTERP_RGB #undef INTERP_ALPHA -- cgit v1.2.3