diff options
| author | Brian <brian@yutani.localnet.net> | 2007-05-02 18:44:34 -0600 | 
|---|---|---|
| committer | Brian <brian@yutani.localnet.net> | 2007-05-02 18:44:34 -0600 | 
| commit | 62da6a1b3e341e53981e2817595e0eea107fe6cb (patch) | |
| tree | ef295d0df9d73159102b8dbc0c2e548344d17342 | |
| parent | 77e7535c0f94b94d26aa2e3d7b19c812beaba2ae (diff) | |
Resuscitate some of the DDX,DDY code.
Only works for program input registers at this time.
Good enough for the common case of texcoords, though.
| -rw-r--r-- | src/mesa/shader/prog_execute.c | 291 | ||||
| -rw-r--r-- | src/mesa/shader/prog_execute.h | 3 | 
2 files changed, 51 insertions, 243 deletions
| diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 356d4ce249..9faf9d8613 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -218,120 +218,64 @@ fetch_vector4(const struct prog_src_register *source,     }  } -#if 0 +  /** - * 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)! + * Fetch the derivative with respect to X or Y for the given register. + * XXX this currently only works for fragment program input attribs.   */ -static GLboolean +static void  fetch_vector4_deriv(GLcontext * ctx,                      const struct prog_src_register *source, -                    const SWspan * span, -                    char xOrY, GLint column, GLfloat result[4]) +                    const struct gl_program_machine *machine, +                    char xOrY, GLfloat result[4])  { -   GLfloat src[4]; +   if (source->File == PROGRAM_INPUT && source->Index < machine->NumDeriv) { +      const GLint col = machine->CurElement; +      const GLfloat w = machine->Attribs[FRAG_ATTRIB_WPOS][col][3]; +      const GLfloat invQ = 1.0f / w; +      GLfloat deriv[4]; -   ASSERT(xOrY == 'X' || xOrY == 'Y'); - -   switch (source->Index) { -   case FRAG_ATTRIB_WPOS:        if (xOrY == 'X') { -         src[0] = 1.0; -         src[1] = 0.0; -         src[2] = span->attrStepX[FRAG_ATTRIB_WPOS][2] -            / ctx->DrawBuffer->_DepthMaxF; -         src[3] = span->attrStepX[FRAG_ATTRIB_WPOS][3]; +         deriv[0] = machine->DerivX[source->Index][0] * invQ; +         deriv[1] = machine->DerivX[source->Index][1] * invQ; +         deriv[2] = machine->DerivX[source->Index][2] * invQ; +         deriv[3] = machine->DerivX[source->Index][3] * invQ;        }        else { -         src[0] = 0.0; -         src[1] = 1.0; -         src[2] = span->attrStepY[FRAG_ATTRIB_WPOS][2] -            / ctx->DrawBuffer->_DepthMaxF; -         src[3] = span->attrStepY[FRAG_ATTRIB_WPOS][3]; -      } -      break; -   case FRAG_ATTRIB_COL0: -   case FRAG_ATTRIB_COL1: -      if (xOrY == 'X') { -         src[0] = span->attrStepX[source->Index][0] * (1.0F / CHAN_MAXF); -         src[1] = span->attrStepX[source->Index][1] * (1.0F / CHAN_MAXF); -         src[2] = span->attrStepX[source->Index][2] * (1.0F / CHAN_MAXF); -         src[3] = span->attrStepX[source->Index][3] * (1.0F / CHAN_MAXF); -      } -      else { -         src[0] = span->attrStepY[source->Index][0] * (1.0F / CHAN_MAXF); -         src[1] = span->attrStepY[source->Index][1] * (1.0F / CHAN_MAXF); -         src[2] = span->attrStepY[source->Index][2] * (1.0F / CHAN_MAXF); -         src[3] = span->attrStepY[source->Index][3] * (1.0F / CHAN_MAXF); -      } -      break; -   case FRAG_ATTRIB_FOGC: -      if (xOrY == 'X') { -         src[0] = span->attrStepX[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF); -         src[1] = 0.0; -         src[2] = 0.0; -         src[3] = 0.0; +         deriv[0] = machine->DerivY[source->Index][0] * invQ; +         deriv[1] = machine->DerivY[source->Index][1] * invQ; +         deriv[2] = machine->DerivY[source->Index][2] * invQ; +         deriv[3] = machine->DerivY[source->Index][3] * invQ;        } -      else { -         src[0] = span->attrStepY[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF); -         src[1] = 0.0; -         src[2] = 0.0; -         src[3] = 0.0; + +      result[0] = deriv[GET_SWZ(source->Swizzle, 0)]; +      result[1] = deriv[GET_SWZ(source->Swizzle, 1)]; +      result[2] = deriv[GET_SWZ(source->Swizzle, 2)]; +      result[3] = deriv[GET_SWZ(source->Swizzle, 3)]; +       +      if (source->NegateBase) { +         result[0] = -result[0]; +         result[1] = -result[1]; +         result[2] = -result[2]; +         result[3] = -result[3];        } -      break; -   default: -      assert(source->Index < FRAG_ATTRIB_MAX); -      /* texcoord or varying */ -      if (xOrY == 'X') { -         /* this is a little tricky - I think I've got it right */ -         const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] -                                      + -                                      span->attrStepX[source->Index][3] * -                                      column); -         src[0] = span->attrStepX[source->Index][0] * invQ; -         src[1] = span->attrStepX[source->Index][1] * invQ; -         src[2] = span->attrStepX[source->Index][2] * invQ; -         src[3] = span->attrStepX[source->Index][3] * invQ; +      if (source->Abs) { +         result[0] = FABSF(result[0]); +         result[1] = FABSF(result[1]); +         result[2] = FABSF(result[2]); +         result[3] = FABSF(result[3]);        } -      else { -         /* Tricky, as above, but in Y direction */ -         const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] -                                      + span->attrStepY[source->Index][3]); -         src[0] = span->attrStepY[source->Index][0] * invQ; -         src[1] = span->attrStepY[source->Index][1] * invQ; -         src[2] = span->attrStepY[source->Index][2] * invQ; -         src[3] = span->attrStepY[source->Index][3] * invQ; +      if (source->NegateAbs) { +         result[0] = -result[0]; +         result[1] = -result[1]; +         result[2] = -result[2]; +         result[3] = -result[3];        } -      break; -   } - -   result[0] = src[GET_SWZ(source->Swizzle, 0)]; -   result[1] = src[GET_SWZ(source->Swizzle, 1)]; -   result[2] = src[GET_SWZ(source->Swizzle, 2)]; -   result[3] = src[GET_SWZ(source->Swizzle, 3)]; - -   if (source->NegateBase) { -      result[0] = -result[0]; -      result[1] = -result[1]; -      result[2] = -result[2]; -      result[3] = -result[3]; -   } -   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]; +   else { +      ASSIGN_4V(result, 0.0, 0.0, 0.0, 0.0);     } -   return GL_TRUE;  } -#endif  /** @@ -519,106 +463,6 @@ store_vector4(const struct prog_instruction *inst,  } -#if 0 -/** - * 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 gl_program_machine *machine, -                   const struct gl_fragment_program *program, -                   const SWspan * span, char xOrY, -                   struct gl_program_machine *dMachine) -{ -   GLuint attr; - -   ASSERT(xOrY == 'X' || xOrY == 'Y'); - -   /* copy existing machine */ -   _mesa_memcpy(dMachine, machine, sizeof(struct gl_program_machine)); - -   if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { -      /* XXX also need to do this when using valgrind */ -      /* Clear temporary registers (undefined for ARB_f_p) */ -      _mesa_bzero((void *) machine->Temporaries, -                  MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); -   } - -   /* Add derivatives */ -   if (program->Base.InputsRead & FRAG_BIT_WPOS) { -      GLfloat *wpos = machine->Attribs[FRAG_ATTRIB_WPOS][machine->CurElement]; -      if (xOrY == 'X') { -         wpos[0] += 1.0F; -         wpos[1] += 0.0F; -         wpos[2] += span->attrStepX[FRAG_ATTRIB_WPOS][2]; -         wpos[3] += span->attrStepX[FRAG_ATTRIB_WPOS][3]; -      } -      else { -         wpos[0] += 0.0F; -         wpos[1] += 1.0F; -         wpos[2] += span->attrStepY[FRAG_ATTRIB_WPOS][2]; -         wpos[3] += span->attrStepY[FRAG_ATTRIB_WPOS][3]; -      } -   } - -   /* primary, secondary colors */ -   for (attr = FRAG_ATTRIB_COL0; attr <= FRAG_ATTRIB_COL1; attr++) { -      if (program->Base.InputsRead & (1 << attr)) { -         GLfloat *col = machine->Attribs[attr][machine->CurElement]; -         if (xOrY == 'X') { -            col[0] += span->attrStepX[attr][0] * (1.0F / CHAN_MAXF); -            col[1] += span->attrStepX[attr][1] * (1.0F / CHAN_MAXF); -            col[2] += span->attrStepX[attr][2] * (1.0F / CHAN_MAXF); -            col[3] += span->attrStepX[attr][3] * (1.0F / CHAN_MAXF); -         } -         else { -            col[0] += span->attrStepY[attr][0] * (1.0F / CHAN_MAXF); -            col[1] += span->attrStepY[attr][1] * (1.0F / CHAN_MAXF); -            col[2] += span->attrStepY[attr][2] * (1.0F / CHAN_MAXF); -            col[3] += span->attrStepY[attr][3] * (1.0F / CHAN_MAXF); -         } -      } -   } -   if (program->Base.InputsRead & FRAG_BIT_FOGC) { -      GLfloat *fogc = machine->Attribs[FRAG_ATTRIB_FOGC][machine->CurElement]; -      if (xOrY == 'X') { -         fogc[0] += span->attrStepX[FRAG_ATTRIB_FOGC][0]; -      } -      else { -         fogc[0] += span->attrStepY[FRAG_ATTRIB_FOGC][0]; -      } -   } -   /* texcoord and varying vars */ -   for (attr = FRAG_ATTRIB_TEX0; attr < FRAG_ATTRIB_MAX; attr++) { -      if (program->Base.InputsRead & (1 << attr)) { -         GLfloat *val = machine->Attribs[attr][machine->CurElement]; -         /* XXX perspective-correct interpolation */ -         if (xOrY == 'X') { -            val[0] += span->attrStepX[attr][0]; -            val[1] += span->attrStepX[attr][1]; -            val[2] += span->attrStepX[attr][2]; -            val[3] += span->attrStepX[attr][3]; -         } -         else { -            val[0] += span->attrStepY[attr][0]; -            val[1] += span->attrStepY[attr][1]; -            val[2] += span->attrStepY[attr][2]; -            val[3] += span->attrStepY[attr][3]; -         } -      } -   } - -   /* init condition codes */ -   dMachine->CondCodes[0] = COND_EQ; -   dMachine->CondCodes[1] = COND_EQ; -   dMachine->CondCodes[2] = COND_EQ; -   dMachine->CondCodes[3] = COND_EQ; -} -#endif - -  /**   * Execute the given vertex/fragment program.   * @@ -762,57 +606,18 @@ _mesa_execute_program(GLcontext * ctx,           break;        case OPCODE_DDX:         /* Partial derivative with respect to X */           { -#if 0 -            GLfloat a[4], aNext[4], result[4]; -            struct gl_program_machine dMachine; -            if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X', -                                     column, 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. -                */ -               fetch_vector4(&inst->SrcReg[0], machine, program, a); -               init_machine_deriv(ctx, machine, program, span, -                                  'X', &dMachine); -               execute_program(ctx, program, pc, &dMachine, span, column); -               fetch_vector4(&inst->SrcReg[0], &dMachine, program, -                             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]; -            } +            GLfloat result[4]; +            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine, +                                'X', result);              store_vector4(inst, machine, result); -#else -            store_vector4(inst, machine, ZeroVec); -#endif           }           break;        case OPCODE_DDY:         /* Partial derivative with respect to Y */           { -#if 0 -            GLfloat a[4], aNext[4], result[4]; -            struct gl_program_machine dMachine; -            if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y', -                                     column, result)) { -               init_machine_deriv(ctx, machine, program, span, -                                  'Y', &dMachine); -               fetch_vector4(&inst->SrcReg[0], machine, program, a); -               execute_program(ctx, program, pc, &dMachine, span, column); -               fetch_vector4(&inst->SrcReg[0], &dMachine, program, -                             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]; -            } +            GLfloat result[4]; +            fetch_vector4_deriv(ctx, &inst->SrcReg[0], machine, +                                'Y', result);              store_vector4(inst, machine, result); -#else -            store_vector4(inst, machine, ZeroVec); -#endif           }           break;        case OPCODE_DP3: diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h index 47845e9111..be29eceeda 100644 --- a/src/mesa/shader/prog_execute.h +++ b/src/mesa/shader/prog_execute.h @@ -48,6 +48,9 @@ struct gl_program_machine     /** Fragment Input attributes */     GLfloat (*Attribs)[MAX_WIDTH][4]; +   GLfloat (*DerivX)[4]; +   GLfloat (*DerivY)[4]; +   GLuint NumDeriv; /**< Max index into DerivX/Y arrays */     GLuint CurElement; /**< Index into Attribs arrays */     /** Vertex Input attribs */ | 
