added new GL_ARB_v_p instructions
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 13 Jun 2003 02:31:42 +0000 (02:31 +0000)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 13 Jun 2003 02:31:42 +0000 (02:31 +0000)
src/mesa/main/nvvertexec.c
src/mesa/main/nvvertprog.h

index 94507aba8808cdbe8f63032f20817c140ccff6f8..bacbea8343c5438a30c9e33995abfa35075e8e58 100644 (file)
@@ -38,6 +38,9 @@
 #include "math/m_matrix.h"
 
 
+static const GLfloat zeroVec[4] = { 0, 0, 0, 0 };
+
+
 /**
  * Load/initialize the vertex program registers.
  * This needs to be done per vertex.
@@ -225,13 +228,12 @@ fetch_vector4( const struct vp_src_register *source,
                const struct vp_machine *machine,
                GLfloat result[4] )
 {
-   static const GLfloat zero[4] = { 0, 0, 0, 0 };
    const GLfloat *src;
 
    if (source->RelAddr) {
       const GLint reg = source->Register + machine->AddressReg;
       if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
-         src = zero;
+         src = zeroVec;
       else
          src = machine->Registers[VP_PROG_REG_START + reg];
    }
@@ -262,13 +264,12 @@ fetch_vector1( const struct vp_src_register *source,
                const struct vp_machine *machine,
                GLfloat result[4] )
 {
-   static const GLfloat zero[4] = { 0, 0, 0, 0 };
    const GLfloat *src;
 
    if (source->RelAddr) {
       const GLint reg = source->Register + machine->AddressReg;
       if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
-         src = zero;
+         src = zeroVec;
       else
          src = machine->Registers[VP_PROG_REG_START + reg];
    }
@@ -606,7 +607,7 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
                store_vector4( &inst->DstReg, machine, t );
             }
             break;
-         case VP_OPCODE_SUB:
+         case VP_OPCODE_SUB: /* GL_NV_vertex_program1_1 */
             {
                GLfloat t[4], u[4], sum[4];
                fetch_vector4( &inst->SrcReg[0], machine, t );
@@ -618,7 +619,7 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
                store_vector4( &inst->DstReg, machine, sum );
             }
             break;
-         case VP_OPCODE_ABS:
+         case VP_OPCODE_ABS: /* GL_NV_vertex_program1_1 */
             {
                GLfloat t[4];
                fetch_vector4( &inst->SrcReg[0], machine, t );
@@ -629,6 +630,97 @@ _mesa_exec_vertex_program(GLcontext *ctx, const struct vertex_program *program)
                store_vector4( &inst->DstReg, machine, t );
             }
             break;
+         case VP_OPCODE_FLR: /* GL_ARB_vertex_program */
+            {
+               GLfloat t[4];
+               fetch_vector4( &inst->SrcReg[0], machine, t );
+               t[0] = FLOORF(t[0]);
+               t[1] = FLOORF(t[1]);
+               t[2] = FLOORF(t[2]);
+               t[3] = FLOORF(t[3]);
+               store_vector4( &inst->DstReg, machine, t );
+            }
+            break;
+         case VP_OPCODE_FRC: /* GL_ARB_vertex_program */
+            {
+               GLfloat t[4];
+               fetch_vector4( &inst->SrcReg[0], machine, t );
+               t[0] = t[0] - FLOORF(t[0]);
+               t[1] = t[1] - FLOORF(t[1]);
+               t[2] = t[2] - FLOORF(t[2]);
+               t[3] = t[3] - FLOORF(t[3]);
+               store_vector4( &inst->DstReg, machine, t );
+            }
+            break;
+         case VP_OPCODE_EX2: /* GL_ARB_vertex_program */
+            {
+               GLfloat t[4];
+               fetch_vector1( &inst->SrcReg[0], machine, t );
+               t[0] = t[1] = t[2] = t[3] = _mesa_pow(2.0, t[0]);
+               store_vector4( &inst->DstReg, machine, t );
+            }
+            break;
+         case VP_OPCODE_LG2: /* GL_ARB_vertex_program */
+            {
+               GLfloat t[4];
+               fetch_vector1( &inst->SrcReg[0], machine, t );
+               t[0] = t[1] = t[2] = t[3] = LOG2(t[0]);
+               store_vector4( &inst->DstReg, machine, t );
+            }
+            break;
+         case VP_OPCODE_POW: /* GL_ARB_vertex_program */
+            {
+               GLfloat t[4], u[4];
+               fetch_vector1( &inst->SrcReg[0], machine, t );
+               fetch_vector1( &inst->SrcReg[1], machine, u );
+               t[0] = t[1] = t[2] = t[3] = _mesa_pow(t[0], u[0]);
+               store_vector4( &inst->DstReg, machine, t );
+            }
+            break;
+         case VP_OPCODE_XPD: /* GL_ARB_vertex_program */
+            {
+               GLfloat t[4], u[4], cross[4];
+               fetch_vector4( &inst->SrcReg[0], machine, t );
+               fetch_vector4( &inst->SrcReg[1], machine, u );
+               cross[0] = t[1] * u[2] - t[2] * u[1];
+               cross[1] = t[2] * u[0] - t[0] * u[2];
+               cross[2] = t[0] * u[1] - t[1] * u[0];
+               store_vector4( &inst->DstReg, machine, cross );
+            }
+            break;
+         case VP_OPCODE_SWZ: /* GL_ARB_vertex_program */
+            {
+               const struct vp_src_register *source = &inst->SrcReg[0];
+               const GLfloat *src;
+               GLfloat result[4];
+               GLuint i;
+
+               /* Code similar to fetch_vector4() */
+               if (source->RelAddr) {
+                  const GLint reg = source->Register + machine->AddressReg;
+                  if (reg < 0 || reg > MAX_NV_VERTEX_PROGRAM_PARAMS)
+                     src = zeroVec;
+                  else
+                     src = machine->Registers[VP_PROG_REG_START + reg];
+               }
+               else {
+                  src = machine->Registers[source->Register];
+               }
+
+               /* extended swizzling here */
+               for (i = 0; i < 3; i++) {
+                  if (source->Swizzle[i] == SWIZZLE_ZERO)
+                     result[i] = 0.0;
+                  else if (source->Swizzle[i] == SWIZZLE_ONE)
+                     result[i] = -1.0;
+                  else
+                     result[i] = -src[source->Swizzle[i]];
+                  if (source->Negate)
+                     result[i] = -result[i];
+               }
+               store_vector4( &inst->DstReg, machine, result );
+            }
+            break;
 
          case VP_OPCODE_END:
             return;
index b96d1133eb6e430fab2fe2f09b6bd1c64213608f..44207e2e4c883d8af1573205b17148aa1e772f06 100644 (file)
 #define VP_PROG_REG_END     (VP_PROG_REG_START + VP_NUM_PROG_REGS - 1)
 
 
+/* for GL_ARB_v_p SWZ instruction */
+#define SWIZZLE_ZERO 100
+#define SWIZZLE_ONE  101
+
+
 /* Vertex program opcodes */
 enum vp_opcode
 {
@@ -72,15 +77,24 @@ enum vp_opcode
    VP_OPCODE_RCC,
    VP_OPCODE_SUB,
    VP_OPCODE_ABS,
-   VP_OPCODE_END
+   VP_OPCODE_END,
+   /* Additional opcodes for GL_ARB_vertex_program */ 
+   VP_OPCODE_FLR,
+   VP_OPCODE_FRC,
+   VP_OPCODE_EX2,
+   VP_OPCODE_LG2,
+   VP_OPCODE_POW,
+   VP_OPCODE_XPD,
+   VP_OPCODE_SWZ
 };
 
 
 /* Instruction source register */
 struct vp_src_register
 {
-   GLint Register;    /* or the offset from the address register */
-   GLuint Swizzle[4];
+   GLint Register;     /* or the offset from the address register */
+   GLubyte Swizzle[4]; /* Each value is 0,1,2,3 for x,y,z,w or */
+                       /* SWIZZLE_ZERO or SWIZZLE_ONE for VP_OPCODE_SWZ. */
    GLboolean Negate;
    GLboolean RelAddr;
 };