+ struct gl_2d_map Map2Attrib[16]; /* GL_NV_vertex_program */
+};
+
+
+/*
+ * Vertex program tokens and datatypes
+ */
+
+#define VP_MAX_INSTRUCTIONS 128
+
+#define VP_NUM_INPUT_REGS VERT_ATTRIB_MAX
+#define VP_NUM_OUTPUT_REGS 15
+#define VP_NUM_TEMP_REGS 12
+#define VP_NUM_PROG_REGS 96
+
+#define VP_NUM_TOTAL_REGISTERS (VP_NUM_INPUT_REGS + VP_NUM_OUTPUT_REGS + VP_NUM_TEMP_REGS + VP_NUM_PROG_REGS)
+
+/* Location of register sets within the whole register file */
+#define VP_INPUT_REG_START 0
+#define VP_INPUT_REG_END (VP_INPUT_REG_START + VP_NUM_INPUT_REGS - 1)
+#define VP_OUTPUT_REG_START (VP_INPUT_REG_END + 1)
+#define VP_OUTPUT_REG_END (VP_OUTPUT_REG_START + VP_NUM_OUTPUT_REGS - 1)
+#define VP_TEMP_REG_START (VP_OUTPUT_REG_END + 1)
+#define VP_TEMP_REG_END (VP_TEMP_REG_START + VP_NUM_TEMP_REGS - 1)
+#define VP_PROG_REG_START (VP_TEMP_REG_END + 1)
+#define VP_PROG_REG_END (VP_PROG_REG_START + VP_NUM_PROG_REGS - 1)
+
+
+/* Machine state (i.e. the register file) */
+struct vp_machine
+{
+ GLfloat Registers[VP_NUM_TOTAL_REGISTERS][4];
+ GLint AddressReg; /* might someday be a 4-vector */
+};
+
+
+/* Vertex program opcodes */
+enum vp_opcode
+{
+ MOV,
+ LIT,
+ RCP,
+ RSQ,
+ EXP,
+ LOG,
+ MUL,
+ ADD,
+ DP3,
+ DP4,
+ DST,
+ MIN,
+ MAX,
+ SLT,
+ SGE,
+ MAD,
+ ARL,
+ DPH,
+ RCC,
+ SUB,
+ ABS,
+ END
+};
+
+
+/* Instruction source register */
+struct vp_src_register
+{
+ GLint Register; /* or the offset from the address register */
+ GLuint Swizzle[4];
+ GLboolean Negate;
+ GLboolean RelAddr;
+};
+
+
+/* Instruction destination register */
+struct vp_dst_register
+{
+ GLint Register;
+ GLboolean WriteMask[4];
+};
+
+
+/* Vertex program instruction */
+struct vp_instruction
+{
+ enum vp_opcode Opcode;
+ struct vp_src_register SrcReg[3];
+ struct vp_dst_register DstReg;
+};
+
+
+/* The actual vertex program, stored in the hash table */
+struct vp_program
+{
+ GLubyte *String; /* Original user code */
+ struct vp_instruction *Instructions; /* Compiled instructions */
+ GLenum Target; /* GL_VERTEX_PROGRAM_NV or GL_VERTEX_STATE_PROGRAM_NV */
+ GLint ErrorPos; /* Position in string where error was detected */
+ GLint RefCount; /* Since programs can be shared among contexts */
+ GLboolean IsPositionInvariant; /* GL_NV_vertex_program1_1 */
+ GLboolean Resident;
+ GLuint InputsRead; /* Bitmask of which input regs are read */
+ GLuint OutputsWritten; /* Bitmask of which output regs are written to */
+};
+
+
+/*
+ * State vars for GL_NV_vertex_program
+ */
+struct vertex_program_state
+{
+ GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */
+ GLboolean PointSizeEnabled; /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
+ GLboolean TwoSideEnabled; /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
+ GLuint CurrentID; /* currently bound program's ID */
+ struct vp_program *Current; /* ptr to currently bound program */
+ struct vp_machine Machine; /* machine state */
+
+ GLenum TrackMatrix[VP_NUM_PROG_REGS / 4];
+ GLenum TrackMatrixTransform[VP_NUM_PROG_REGS / 4];