/*
* Mesa 3-D graphics library
- * Version: 6.0.1
+ * Version: 6.5.2
*
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
#include "mtypes.h"
#include "nvprogram.h"
#include "nvvertparse.h"
-#include "nvvertprog.h"
+#include "program_instruction.h"
#include "program.h"
GLboolean isStateProgram;
GLboolean isPositionInvariant;
GLboolean isVersion1_1;
- GLuint inputsRead;
- GLuint outputsWritten;
+ GLbitfield inputsRead;
+ GLbitfield outputsWritten;
GLboolean anyProgRegsWritten;
GLuint numInst; /* number of instructions parsed */
};
parseState->pos += (-i);
return GL_FALSE;
}
- len = _mesa_strlen((const char *) token);
+ len = (GLint)_mesa_strlen((const char *) token);
parseState->pos += (i - len);
return GL_TRUE;
}
};
static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
- "HPOS", "COL0", "COL1", "BFC0", "BFC1", "FOGC", "PSIZ",
- "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
-};
-
-/* NOTE: the order here must match opcodes in nvvertprog.h */
-static const char *Opcodes[] = {
- "MOV", "LIT", "RCP", "RSQ", "EXP", "LOG", "MUL", "ADD", "DP3", "DP4",
- "DST", "MIN", "MAX", "SLT", "SGE", "MAD", "ARL", "DPH", "RCC", "SUB",
- "ABS", "END",
- /* GL_ARB_vertex_program */
- "FLR", "FRC", "EX2", "LG2", "POW", "XPD", "SWZ",
- NULL
+ "HPOS", "COL0", "COL1", "FOGC",
+ "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7",
+ "PSIZ", "BFC0", "BFC1", NULL
};
static GLboolean
-Parse_ParamReg(struct parse_state *parseState, struct vp_src_register *srcReg)
+Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg)
{
GLubyte token[100];
static GLboolean
-Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstReg)
+Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg)
{
GLubyte token[100];
+ GLint idx;
/* Dst reg can be R<n> or o[n] */
if (!Peek_Token(parseState, token))
if (token[0] == 'R') {
/* a temporary register */
dstReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &dstReg->Index))
+ if (!Parse_TempReg(parseState, &idx))
RETURN_ERROR;
+ dstReg->Index = idx;
}
else if (!parseState->isStateProgram && token[0] == 'o') {
/* an output register */
dstReg->File = PROGRAM_OUTPUT;
- if (!Parse_OutputReg(parseState, &dstReg->Index))
+ if (!Parse_OutputReg(parseState, &idx))
RETURN_ERROR;
+ dstReg->Index = idx;
}
else if (parseState->isStateProgram && token[0] == 'c' &&
parseState->isStateProgram) {
/* absolute program parameter register */
/* Only valid for vertex state programs */
dstReg->File = PROGRAM_ENV_PARAM;
- if (!Parse_AbsParamReg(parseState, &dstReg->Index))
+ if (!Parse_AbsParamReg(parseState, &idx))
RETURN_ERROR;
+ dstReg->Index = idx;
}
else {
RETURN_ERROR1("Bad destination register name");
if (!Parse_Token(parseState, token))
RETURN_ERROR;
- dstReg->WriteMask[0] = GL_FALSE;
- dstReg->WriteMask[1] = GL_FALSE;
- dstReg->WriteMask[2] = GL_FALSE;
- dstReg->WriteMask[3] = GL_FALSE;
+ dstReg->WriteMask = 0;
if (token[k] == 'x') {
- dstReg->WriteMask[0] = GL_TRUE;
+ dstReg->WriteMask |= WRITEMASK_X;
k++;
}
if (token[k] == 'y') {
- dstReg->WriteMask[1] = GL_TRUE;
+ dstReg->WriteMask |= WRITEMASK_Y;
k++;
}
if (token[k] == 'z') {
- dstReg->WriteMask[2] = GL_TRUE;
+ dstReg->WriteMask |= WRITEMASK_Z;
k++;
}
if (token[k] == 'w') {
- dstReg->WriteMask[3] = GL_TRUE;
+ dstReg->WriteMask |= WRITEMASK_W;
k++;
}
if (k == 0) {
return GL_TRUE;
}
else {
- dstReg->WriteMask[0] = GL_TRUE;
- dstReg->WriteMask[1] = GL_TRUE;
- dstReg->WriteMask[2] = GL_TRUE;
- dstReg->WriteMask[3] = GL_TRUE;
+ dstReg->WriteMask = WRITEMASK_XYZW;
return GL_TRUE;
}
}
static GLboolean
-Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg)
+Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
{
GLubyte token[100];
+ GLint idx;
srcReg->RelAddr = GL_FALSE;
RETURN_ERROR;
if (token[0] == '-') {
(void) Parse_String(parseState, "-");
- srcReg->Negate = GL_TRUE;
+ srcReg->NegateBase = NEGATE_XYZW;
if (!Peek_Token(parseState, token))
RETURN_ERROR;
}
else {
- srcReg->Negate = GL_FALSE;
+ srcReg->NegateBase = NEGATE_NONE;
}
/* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
if (token[0] == 'R') {
srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &srcReg->Index))
+ if (!Parse_TempReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else if (token[0] == 'c') {
if (!Parse_ParamReg(parseState, srcReg))
}
else if (token[0] == 'v') {
srcReg->File = PROGRAM_INPUT;
- if (!Parse_AttribReg(parseState, &srcReg->Index))
+ if (!Parse_AttribReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else {
RETURN_ERROR2("Bad source register name", token);
}
/* init swizzle fields */
- srcReg->Swizzle[0] = 0;
- srcReg->Swizzle[1] = 1;
- srcReg->Swizzle[2] = 2;
- srcReg->Swizzle[3] = 3;
+ srcReg->Swizzle = SWIZZLE_NOOP;
/* Look for optional swizzle suffix */
if (!Peek_Token(parseState, token))
if (token[1] == 0) {
/* single letter swizzle */
if (token[0] == 'x')
- ASSIGN_4V(srcReg->Swizzle, 0, 0, 0, 0);
+ srcReg->Swizzle = MAKE_SWIZZLE4(0, 0, 0, 0);
else if (token[0] == 'y')
- ASSIGN_4V(srcReg->Swizzle, 1, 1, 1, 1);
+ srcReg->Swizzle = MAKE_SWIZZLE4(1, 1, 1, 1);
else if (token[0] == 'z')
- ASSIGN_4V(srcReg->Swizzle, 2, 2, 2, 2);
+ srcReg->Swizzle = MAKE_SWIZZLE4(2, 2, 2, 2);
else if (token[0] == 'w')
- ASSIGN_4V(srcReg->Swizzle, 3, 3, 3, 3);
+ srcReg->Swizzle = MAKE_SWIZZLE4(3, 3, 3, 3);
else
RETURN_ERROR1("Expected x, y, z, or w");
}
else {
/* 2, 3 or 4-component swizzle */
GLint k;
+
+ srcReg->Swizzle = 0;
+
for (k = 0; token[k] && k < 5; k++) {
if (token[k] == 'x')
- srcReg->Swizzle[k] = 0;
+ srcReg->Swizzle |= 0 << (k*3);
else if (token[k] == 'y')
- srcReg->Swizzle[k] = 1;
+ srcReg->Swizzle |= 1 << (k*3);
else if (token[k] == 'z')
- srcReg->Swizzle[k] = 2;
+ srcReg->Swizzle |= 2 << (k*3);
else if (token[k] == 'w')
- srcReg->Swizzle[k] = 3;
+ srcReg->Swizzle |= 3 << (k*3);
else
RETURN_ERROR;
}
static GLboolean
-Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcReg)
+Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
{
GLubyte token[100];
+ GLint idx;
srcReg->RelAddr = GL_FALSE;
if (!Peek_Token(parseState, token))
RETURN_ERROR;
if (token[0] == '-') {
- srcReg->Negate = GL_TRUE;
+ srcReg->NegateBase = NEGATE_XYZW;
(void) Parse_String(parseState, "-"); /* consume '-' */
if (!Peek_Token(parseState, token))
RETURN_ERROR;
}
else {
- srcReg->Negate = GL_FALSE;
+ srcReg->NegateBase = NEGATE_NONE;
}
/* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
if (token[0] == 'R') {
srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &srcReg->Index))
+ if (!Parse_TempReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else if (token[0] == 'c') {
if (!Parse_ParamReg(parseState, srcReg))
}
else if (token[0] == 'v') {
srcReg->File = PROGRAM_INPUT;
- if (!Parse_AttribReg(parseState, &srcReg->Index))
+ if (!Parse_AttribReg(parseState, &idx))
RETURN_ERROR;
+ srcReg->Index = idx;
}
else {
RETURN_ERROR2("Bad source register name", token);
RETURN_ERROR;
if (token[0] == 'x' && token[1] == 0) {
- srcReg->Swizzle[0] = 0;
+ srcReg->Swizzle = 0;
}
else if (token[0] == 'y' && token[1] == 0) {
- srcReg->Swizzle[0] = 1;
+ srcReg->Swizzle = 1;
}
else if (token[0] == 'z' && token[1] == 0) {
- srcReg->Swizzle[0] = 2;
+ srcReg->Swizzle = 2;
}
else if (token[0] == 'w' && token[1] == 0) {
- srcReg->Swizzle[0] = 3;
+ srcReg->Swizzle = 3;
}
else {
RETURN_ERROR1("Bad scalar source suffix");
}
- srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0;
return GL_TRUE;
}
static GLint
Parse_UnaryOpInstruction(struct parse_state *parseState,
- struct vp_instruction *inst, enum vp_opcode opcode)
+ struct prog_instruction *inst,
+ enum prog_opcode opcode)
{
- if (opcode == VP_OPCODE_ABS && !parseState->isVersion1_1)
+ if (opcode == OPCODE_ABS && !parseState->isVersion1_1)
RETURN_ERROR1("ABS illegal for vertex program 1.0");
inst->Opcode = opcode;
static GLboolean
Parse_BiOpInstruction(struct parse_state *parseState,
- struct vp_instruction *inst, enum vp_opcode opcode)
+ struct prog_instruction *inst,
+ enum prog_opcode opcode)
{
- if (opcode == VP_OPCODE_DPH && !parseState->isVersion1_1)
+ if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
RETURN_ERROR1("DPH illegal for vertex program 1.0");
- if (opcode == VP_OPCODE_SUB && !parseState->isVersion1_1)
+ if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
RETURN_ERROR1("SUB illegal for vertex program 1.0");
inst->Opcode = opcode;
static GLboolean
Parse_TriOpInstruction(struct parse_state *parseState,
- struct vp_instruction *inst, enum vp_opcode opcode)
+ struct prog_instruction *inst,
+ enum prog_opcode opcode)
{
inst->Opcode = opcode;
inst->StringPos = parseState->curLine - parseState->start;
static GLboolean
Parse_ScalarInstruction(struct parse_state *parseState,
- struct vp_instruction *inst, enum vp_opcode opcode)
+ struct prog_instruction *inst,
+ enum prog_opcode opcode)
{
- if (opcode == VP_OPCODE_RCC && !parseState->isVersion1_1)
+ if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
RETURN_ERROR1("RCC illegal for vertex program 1.0");
inst->Opcode = opcode;
static GLboolean
-Parse_AddressInstruction(struct parse_state *parseState, struct vp_instruction *inst)
+Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
{
- inst->Opcode = VP_OPCODE_ARL;
+ inst->Opcode = OPCODE_ARL;
inst->StringPos = parseState->curLine - parseState->start;
+ /* Make ARB_vp backends happy */
+ inst->DstReg.File = PROGRAM_ADDRESS;
+ inst->DstReg.WriteMask = WRITEMASK_X;
+ inst->DstReg.Index = 0;
+
/* dest A0 reg */
if (!Parse_AddrReg(parseState))
RETURN_ERROR;
static GLboolean
-Parse_EndInstruction(struct parse_state *parseState, struct vp_instruction *inst)
+Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst)
{
GLubyte token[100];
- inst->Opcode = VP_OPCODE_END;
+ inst->Opcode = OPCODE_END;
inst->StringPos = parseState->curLine - parseState->start;
/* this should fail! */
}
+/**
+ * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
+ * the vertex program developer.
+ * The NV_vertex_program extension grammar is modified as follows:
+ *
+ * <instruction> ::= <ARL-instruction>
+ * | ...
+ * | <PRINT-instruction>
+ *
+ * <PRINT-instruction> ::= "PRINT" <string literal>
+ * | "PRINT" <string literal> "," <srcReg>
+ * | "PRINT" <string literal> "," <dstReg>
+ */
+static GLboolean
+Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+ const GLubyte *str;
+ GLubyte *msg;
+ GLuint len;
+ GLubyte token[100];
+ struct prog_src_register *srcReg = &inst->SrcReg[0];
+ GLint idx;
+
+ inst->Opcode = OPCODE_PRINT;
+ inst->StringPos = parseState->curLine - parseState->start;
+
+ /* The first argument is a literal string 'just like this' */
+ if (!Parse_String(parseState, "'"))
+ RETURN_ERROR;
+
+ str = parseState->pos;
+ for (len = 0; str[len] != '\''; len++) /* find closing quote */
+ ;
+ parseState->pos += len + 1;
+ msg = (GLubyte*) _mesa_malloc(len + 1);
+
+ _mesa_memcpy(msg, str, len);
+ msg[len] = 0;
+ inst->Data = msg;
+
+ /* comma */
+ if (Parse_String(parseState, ",")) {
+
+ /* The second argument is a register name */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+
+ srcReg->RelAddr = GL_FALSE;
+ srcReg->NegateBase = NEGATE_NONE;
+ srcReg->Swizzle = SWIZZLE_NOOP;
+
+ /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
+ * or an o[n] output register.
+ */
+ if (token[0] == 'R') {
+ srcReg->File = PROGRAM_TEMPORARY;
+ if (!Parse_TempReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else if (token[0] == 'c') {
+ srcReg->File = PROGRAM_ENV_PARAM;
+ if (!Parse_ParamReg(parseState, srcReg))
+ RETURN_ERROR;
+ }
+ else if (token[0] == 'v') {
+ srcReg->File = PROGRAM_INPUT;
+ if (!Parse_AttribReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else if (token[0] == 'o') {
+ srcReg->File = PROGRAM_OUTPUT;
+ if (!Parse_OutputReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else {
+ RETURN_ERROR2("Bad source register name", token);
+ }
+ }
+ else {
+ srcReg->File = 0;
+ }
+
+ /* semicolon */
+ if (!Parse_String(parseState, ";"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
static GLboolean
Parse_OptionSequence(struct parse_state *parseState,
- struct vp_instruction program[])
+ struct prog_instruction program[])
{
+ (void) program;
while (1) {
if (!Parse_String(parseState, "OPTION"))
return GL_TRUE; /* ok, not an OPTION statement */
static GLboolean
Parse_InstructionSequence(struct parse_state *parseState,
- struct vp_instruction program[])
+ struct prog_instruction program[])
{
while (1) {
- struct vp_instruction *inst = program + parseState->numInst;
+ struct prog_instruction *inst = program + parseState->numInst;
/* Initialize the instruction */
- inst->SrcReg[0].File = (enum register_file) -1;
- inst->SrcReg[1].File = (enum register_file) -1;
- inst->SrcReg[2].File = (enum register_file) -1;
- inst->DstReg.File = (enum register_file) -1;
+ _mesa_init_instructions(inst, 1);
if (Parse_String(parseState, "MOV")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_MOV))
+ if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))
RETURN_ERROR;
}
else if (Parse_String(parseState, "LIT")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_LIT))
+ if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))
RETURN_ERROR;
}
else if (Parse_String(parseState, "ABS")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, VP_OPCODE_ABS))
+ if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))
RETURN_ERROR;
}
else if (Parse_String(parseState, "MUL")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MUL))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))
RETURN_ERROR;
}
else if (Parse_String(parseState, "ADD")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_ADD))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))
RETURN_ERROR;
}
else if (Parse_String(parseState, "DP3")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DP3))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))
RETURN_ERROR;
}
else if (Parse_String(parseState, "DP4")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DP4))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))
RETURN_ERROR;
}
else if (Parse_String(parseState, "DST")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DST))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))
RETURN_ERROR;
}
else if (Parse_String(parseState, "MIN")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MIN))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))
RETURN_ERROR;
}
else if (Parse_String(parseState, "MAX")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_MAX))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))
RETURN_ERROR;
}
else if (Parse_String(parseState, "SLT")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SLT))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))
RETURN_ERROR;
}
else if (Parse_String(parseState, "SGE")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SGE))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))
RETURN_ERROR;
}
else if (Parse_String(parseState, "DPH")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_DPH))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))
RETURN_ERROR;
}
else if (Parse_String(parseState, "SUB")) {
- if (!Parse_BiOpInstruction(parseState, inst, VP_OPCODE_SUB))
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))
RETURN_ERROR;
}
else if (Parse_String(parseState, "MAD")) {
- if (!Parse_TriOpInstruction(parseState, inst, VP_OPCODE_MAD))
+ if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))
RETURN_ERROR;
}
else if (Parse_String(parseState, "RCP")) {
- if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_RCP))
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))
RETURN_ERROR;
}
else if (Parse_String(parseState, "RSQ")) {
- if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_RSQ))
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))
RETURN_ERROR;
}
else if (Parse_String(parseState, "EXP")) {
- if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_EXP))
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))
RETURN_ERROR;
}
else if (Parse_String(parseState, "LOG")) {
- if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_LOG))
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))
RETURN_ERROR;
}
else if (Parse_String(parseState, "RCC")) {
- if (!Parse_ScalarInstruction(parseState, inst, VP_OPCODE_RCC))
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))
RETURN_ERROR;
}
else if (Parse_String(parseState, "ARL")) {
if (!Parse_AddressInstruction(parseState, inst))
RETURN_ERROR;
}
+ else if (Parse_String(parseState, "PRINT")) {
+ if (!Parse_PrintInstruction(parseState, inst))
+ RETURN_ERROR;
+ }
else if (Parse_String(parseState, "END")) {
if (!Parse_EndInstruction(parseState, inst))
RETURN_ERROR;
static GLboolean
Parse_Program(struct parse_state *parseState,
- struct vp_instruction instBuffer[])
+ struct prog_instruction instBuffer[])
{
if (parseState->isVersion1_1) {
if (!Parse_OptionSequence(parseState, instBuffer)) {
void
_mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
const GLubyte *str, GLsizei len,
- struct vertex_program *program)
+ struct gl_vertex_program *program)
{
struct parse_state parseState;
- struct vp_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
- struct vp_instruction *newInst;
+ struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
+ struct prog_instruction *newInst;
GLenum target;
GLubyte *programString;
}
else {
if (!parseState.isPositionInvariant &&
- !(parseState.outputsWritten & 1)) {
+ !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) {
/* bit 1 = HPOS register */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glLoadProgramNV(HPOS not written)");
/* copy the compiled instructions */
assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
- newInst = (struct vp_instruction *)
- MALLOC(parseState.numInst * sizeof(struct vp_instruction));
+ newInst = _mesa_alloc_instructions(parseState.numInst);
if (!newInst) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
- FREE(programString);
+ _mesa_free(programString);
return; /* out of memory */
}
- MEMCPY(newInst, instBuffer,
- parseState.numInst * sizeof(struct vp_instruction));
+ _mesa_memcpy(newInst, instBuffer,
+ parseState.numInst * sizeof(struct prog_instruction));
/* install the program */
program->Base.Target = target;
if (program->Base.String) {
- FREE(program->Base.String);
+ _mesa_free(program->Base.String);
}
program->Base.String = programString;
program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
- if (program->Instructions) {
- FREE(program->Instructions);
+ if (program->Base.Instructions) {
+ _mesa_free(program->Base.Instructions);
}
- program->Instructions = newInst;
- program->InputsRead = parseState.inputsRead;
- program->OutputsWritten = parseState.outputsWritten;
+ program->Base.Instructions = newInst;
+ program->Base.InputsRead = parseState.inputsRead;
+ if (parseState.isPositionInvariant)
+ program->Base.InputsRead |= VERT_BIT_POS;
+ program->Base.NumInstructions = parseState.numInst;
+ program->Base.OutputsWritten = parseState.outputsWritten;
program->IsPositionInvariant = parseState.isPositionInvariant;
+ program->IsNVProgram = GL_TRUE;
-#ifdef DEBUG
+#ifdef DEBUG_foo
_mesa_printf("--- glLoadProgramNV result ---\n");
_mesa_print_nv_vertex_program(program);
_mesa_printf("------------------------------\n");
static void
-PrintSrcReg(const struct vp_src_register *src)
+PrintSrcReg(const struct prog_src_register *src)
{
static const char comps[5] = "xyzw";
- if (src->Negate)
+ if (src->NegateBase)
_mesa_printf("-");
if (src->RelAddr) {
if (src->Index > 0)
_mesa_printf("R%d", src->Index);
}
- if (src->Swizzle[0] == src->Swizzle[1] &&
- src->Swizzle[0] == src->Swizzle[2] &&
- src->Swizzle[0] == src->Swizzle[3]) {
- _mesa_printf(".%c", comps[src->Swizzle[0]]);
+ if (GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 1) &&
+ GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 2) &&
+ GET_SWZ(src->Swizzle, 0) == GET_SWZ(src->Swizzle, 3)) {
+ _mesa_printf(".%c", comps[GET_SWZ(src->Swizzle, 0)]);
}
- else if (src->Swizzle[0] != 0 ||
- src->Swizzle[1] != 1 ||
- src->Swizzle[2] != 2 ||
- src->Swizzle[3] != 3) {
+ else if (src->Swizzle != SWIZZLE_NOOP) {
_mesa_printf(".%c%c%c%c",
- comps[src->Swizzle[0]],
- comps[src->Swizzle[1]],
- comps[src->Swizzle[2]],
- comps[src->Swizzle[3]]);
+ comps[GET_SWZ(src->Swizzle, 0)],
+ comps[GET_SWZ(src->Swizzle, 1)],
+ comps[GET_SWZ(src->Swizzle, 2)],
+ comps[GET_SWZ(src->Swizzle, 3)]);
}
}
static void
-PrintDstReg(const struct vp_dst_register *dst)
+PrintDstReg(const struct prog_dst_register *dst)
{
- GLint w = dst->WriteMask[0] + dst->WriteMask[1]
- + dst->WriteMask[2] + dst->WriteMask[3];
-
if (dst->File == PROGRAM_OUTPUT) {
_mesa_printf("o[%s]", OutputRegisters[dst->Index]);
}
_mesa_printf("R%d", dst->Index);
}
- if (w != 0 && w != 4) {
+ if (dst->WriteMask != 0 && dst->WriteMask != WRITEMASK_XYZW) {
_mesa_printf(".");
- if (dst->WriteMask[0])
+ if (dst->WriteMask & WRITEMASK_X)
_mesa_printf("x");
- if (dst->WriteMask[1])
+ if (dst->WriteMask & WRITEMASK_Y)
_mesa_printf("y");
- if (dst->WriteMask[2])
+ if (dst->WriteMask & WRITEMASK_Z)
_mesa_printf("z");
- if (dst->WriteMask[3])
+ if (dst->WriteMask & WRITEMASK_W)
_mesa_printf("w");
}
}
* Print a single NVIDIA vertex program instruction.
*/
void
-_mesa_print_nv_vertex_instruction(const struct vp_instruction *inst)
+_mesa_print_nv_vertex_instruction(const struct prog_instruction *inst)
{
+ GLuint i, n;
+
switch (inst->Opcode) {
- case VP_OPCODE_MOV:
- case VP_OPCODE_LIT:
- case VP_OPCODE_RCP:
- case VP_OPCODE_RSQ:
- case VP_OPCODE_EXP:
- case VP_OPCODE_LOG:
- case VP_OPCODE_RCC:
- case VP_OPCODE_ABS:
- _mesa_printf("%s ", Opcodes[(int) inst->Opcode]);
+ case OPCODE_MOV:
+ case OPCODE_LIT:
+ case OPCODE_RCP:
+ case OPCODE_RSQ:
+ case OPCODE_EXP:
+ case OPCODE_LOG:
+ case OPCODE_RCC:
+ case OPCODE_ABS:
+ case OPCODE_MUL:
+ case OPCODE_ADD:
+ case OPCODE_DP3:
+ case OPCODE_DP4:
+ case OPCODE_DST:
+ case OPCODE_MIN:
+ case OPCODE_MAX:
+ case OPCODE_SLT:
+ case OPCODE_SGE:
+ case OPCODE_DPH:
+ case OPCODE_SUB:
+ case OPCODE_MAD:
+ _mesa_printf("%s ", _mesa_opcode_string(inst->Opcode));
PrintDstReg(&inst->DstReg);
_mesa_printf(", ");
- PrintSrcReg(&inst->SrcReg[0]);
- _mesa_printf(";\n");
- break;
- case VP_OPCODE_MUL:
- case VP_OPCODE_ADD:
- case VP_OPCODE_DP3:
- case VP_OPCODE_DP4:
- case VP_OPCODE_DST:
- case VP_OPCODE_MIN:
- case VP_OPCODE_MAX:
- case VP_OPCODE_SLT:
- case VP_OPCODE_SGE:
- case VP_OPCODE_DPH:
- case VP_OPCODE_SUB:
- _mesa_printf("%s ", Opcodes[(int) inst->Opcode]);
- PrintDstReg(&inst->DstReg);
- _mesa_printf(", ");
- PrintSrcReg(&inst->SrcReg[0]);
- _mesa_printf(", ");
- PrintSrcReg(&inst->SrcReg[1]);
- _mesa_printf(";\n");
- break;
- case VP_OPCODE_MAD:
- _mesa_printf("MAD ");
- PrintDstReg(&inst->DstReg);
- _mesa_printf(", ");
- PrintSrcReg(&inst->SrcReg[0]);
- _mesa_printf(", ");
- PrintSrcReg(&inst->SrcReg[1]);
- _mesa_printf(", ");
- PrintSrcReg(&inst->SrcReg[2]);
+ n = _mesa_num_inst_src_regs(inst->Opcode);
+ for (i = 0; i < n; i++) {
+ PrintSrcReg(&inst->SrcReg[i]);
+ if (i + 1 < n)
+ _mesa_printf(", ");
+ }
_mesa_printf(";\n");
break;
- case VP_OPCODE_ARL:
+ case OPCODE_ARL:
_mesa_printf("ARL A0.x, ");
PrintSrcReg(&inst->SrcReg[0]);
_mesa_printf(";\n");
break;
- case VP_OPCODE_END:
+ case OPCODE_PRINT:
+ _mesa_printf("PRINT '%s'", inst->Data);
+ if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) {
+ _mesa_printf(", ");
+ PrintSrcReg(&inst->SrcReg[0]);
+ _mesa_printf(";\n");
+ }
+ else {
+ _mesa_printf("\n");
+ }
+ break;
+ case OPCODE_END:
_mesa_printf("END\n");
break;
default:
* Print (unparse) the given vertex program. Just for debugging.
*/
void
-_mesa_print_nv_vertex_program(const struct vertex_program *program)
+_mesa_print_nv_vertex_program(const struct gl_vertex_program *program)
{
- const struct vp_instruction *inst;
+ const struct prog_instruction *inst;
- for (inst = program->Instructions; ; inst++) {
+ for (inst = program->Base.Instructions; ; inst++) {
_mesa_print_nv_vertex_instruction(inst);
- if (inst->Opcode == VP_OPCODE_END)
+ if (inst->Opcode == OPCODE_END)
return;
}
}
ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
return OutputRegisters[i];
}
+