X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fshader%2Fnvvertparse.c;h=f5e2df267081dbe2cc41cbe4e2c22c1142b9298b;hb=2f1c5c58b33dc616a3744cd40fcae20971309b3c;hp=7e8e749d8cc2685b3058f3ffd19d2b41e05306ae;hpb=a6c423d95663cfd8601cf84e10e8e1b12fa6ef15;p=mesa.git diff --git a/src/mesa/shader/nvvertparse.c b/src/mesa/shader/nvvertparse.c index 7e8e749d8cc..f5e2df26708 100644 --- a/src/mesa/shader/nvvertparse.c +++ b/src/mesa/shader/nvvertparse.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.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"), @@ -37,15 +37,14 @@ * including any use thereof or modifications thereto. */ -#include "glheader.h" -#include "context.h" -#include "hash.h" -#include "imports.h" -#include "macros.h" -#include "mtypes.h" +#include "main/glheader.h" +#include "main/context.h" +#include "main/imports.h" +#include "main/macros.h" #include "nvprogram.h" #include "nvvertparse.h" -#include "nvvertprog.h" +#include "prog_instruction.h" +#include "prog_print.h" #include "program.h" @@ -62,8 +61,8 @@ struct parse_state { GLboolean isStateProgram; GLboolean isPositionInvariant; GLboolean isVersion1_1; - GLuint inputsRead; - GLuint outputsWritten; + GLbitfield inputsRead; + GLbitfield outputsWritten; GLboolean anyProgRegsWritten; GLuint numInst; /* number of instructions parsed */ }; @@ -233,7 +232,7 @@ Peek_Token(struct parse_state *parseState, GLubyte *token) 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; } @@ -288,18 +287,9 @@ static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = { }; 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 }; @@ -390,7 +380,7 @@ Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum) 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]; @@ -558,9 +548,10 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum) 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 or o[n] */ if (!Peek_Token(parseState, token)) @@ -569,22 +560,25 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe 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"); @@ -604,25 +598,22 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe 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) { @@ -631,19 +622,17 @@ Parse_MaskedDstReg(struct parse_state *parseState, struct vp_dst_register *dstRe 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; @@ -652,19 +641,20 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR RETURN_ERROR; if (token[0] == '-') { (void) Parse_String(parseState, "-"); - srcReg->Negate = GL_TRUE; + srcReg->Negate = NEGATE_XYZW; if (!Peek_Token(parseState, token)) RETURN_ERROR; } else { - srcReg->Negate = GL_FALSE; + srcReg->Negate = NEGATE_NONE; } /* Src reg can be R, 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)) @@ -672,18 +662,16 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR } 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)) @@ -697,28 +685,31 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR if (token[1] == 0) { /* single letter swizzle */ if (token[0] == 'x') - ASSIGN_4V(srcReg->Swizzle, 0, 0, 0, 0); + srcReg->Swizzle = SWIZZLE_XXXX; else if (token[0] == 'y') - ASSIGN_4V(srcReg->Swizzle, 1, 1, 1, 1); + srcReg->Swizzle = SWIZZLE_YYYY; else if (token[0] == 'z') - ASSIGN_4V(srcReg->Swizzle, 2, 2, 2, 2); + srcReg->Swizzle = SWIZZLE_ZZZZ; else if (token[0] == 'w') - ASSIGN_4V(srcReg->Swizzle, 3, 3, 3, 3); + srcReg->Swizzle = SWIZZLE_WWWW; 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; } @@ -732,9 +723,10 @@ Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_src_register *srcR 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; @@ -742,20 +734,21 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe if (!Peek_Token(parseState, token)) RETURN_ERROR; if (token[0] == '-') { - srcReg->Negate = GL_TRUE; + srcReg->Negate = NEGATE_XYZW; (void) Parse_String(parseState, "-"); /* consume '-' */ if (!Peek_Token(parseState, token)) RETURN_ERROR; } else { - srcReg->Negate = GL_FALSE; + srcReg->Negate = NEGATE_NONE; } /* Src reg can be R, 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)) @@ -763,8 +756,9 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe } 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); @@ -778,21 +772,20 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe 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; } @@ -800,13 +793,13 @@ Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_src_register *srcRe 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; - inst->StringPos = parseState->curLine - parseState->start; /* dest reg */ if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) @@ -830,15 +823,15 @@ Parse_UnaryOpInstruction(struct parse_state *parseState, 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; - inst->StringPos = parseState->curLine - parseState->start; /* dest reg */ if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) @@ -882,10 +875,10 @@ Parse_BiOpInstruction(struct parse_state *parseState, 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; /* dest reg */ if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) @@ -949,13 +942,13 @@ Parse_TriOpInstruction(struct parse_state *parseState, 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; - inst->StringPos = parseState->curLine - parseState->start; /* dest reg */ if (!Parse_MaskedDstReg(parseState, &inst->DstReg)) @@ -978,10 +971,14 @@ Parse_ScalarInstruction(struct parse_state *parseState, 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->StringPos = parseState->curLine - parseState->start; + inst->Opcode = OPCODE_ARL; + + /* 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)) @@ -1004,12 +1001,11 @@ Parse_AddressInstruction(struct parse_state *parseState, struct vp_instruction * 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->StringPos = parseState->curLine - parseState->start; + inst->Opcode = OPCODE_END; /* this should fail! */ if (Parse_Token(parseState, token)) @@ -1019,9 +1015,101 @@ Parse_EndInstruction(struct parse_state *parseState, struct vp_instruction *inst } +/** + * 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: + * + * ::= + * | ... + * | + * + * ::= "PRINT" + * | "PRINT" "," + * | "PRINT" "," + */ +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; + + /* 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->Negate = NEGATE_NONE; + srcReg->Swizzle = SWIZZLE_NOOP; + + /* Register can be R, 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) { @@ -1041,101 +1129,102 @@ Parse_OptionSequence(struct parse_state *parseState, 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; @@ -1174,7 +1263,7 @@ Parse_InstructionSequence(struct parse_state *parseState, 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)) { @@ -1193,11 +1282,11 @@ Parse_Program(struct parse_state *parseState, 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; @@ -1267,7 +1356,7 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, } 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)"); @@ -1277,35 +1366,36 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, /* 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_copy_instructions(newInst, instBuffer, parseState.numInst); /* 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_foo _mesa_printf("--- glLoadProgramNV result ---\n"); - _mesa_print_nv_vertex_program(program); + _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0); _mesa_printf("------------------------------\n"); #endif } @@ -1321,167 +1411,6 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget, } -static void -PrintSrcReg(const struct vp_src_register *src) -{ - static const char comps[5] = "xyzw"; - if (src->Negate) - _mesa_printf("-"); - if (src->RelAddr) { - if (src->Index > 0) - _mesa_printf("c[A0.x + %d]", src->Index); - else if (src->Index < 0) - _mesa_printf("c[A0.x - %d]", -src->Index); - else - _mesa_printf("c[A0.x]"); - } - else if (src->File == PROGRAM_OUTPUT) { - _mesa_printf("o[%s]", OutputRegisters[src->Index]); - } - else if (src->File == PROGRAM_INPUT) { - _mesa_printf("v[%s]", InputRegisters[src->Index]); - } - else if (src->File == PROGRAM_ENV_PARAM) { - _mesa_printf("c[%d]", src->Index); - } - else { - ASSERT(src->File == PROGRAM_TEMPORARY); - _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]]); - } - else if (src->Swizzle[0] != 0 || - src->Swizzle[1] != 1 || - src->Swizzle[2] != 2 || - src->Swizzle[3] != 3) { - _mesa_printf(".%c%c%c%c", - comps[src->Swizzle[0]], - comps[src->Swizzle[1]], - comps[src->Swizzle[2]], - comps[src->Swizzle[3]]); - } -} - - -static void -PrintDstReg(const struct vp_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]); - } - else if (dst->File == PROGRAM_INPUT) { - _mesa_printf("v[%s]", InputRegisters[dst->Index]); - } - else if (dst->File == PROGRAM_ENV_PARAM) { - _mesa_printf("c[%d]", dst->Index); - } - else { - ASSERT(dst->File == PROGRAM_TEMPORARY); - _mesa_printf("R%d", dst->Index); - } - - if (w != 0 && w != 4) { - _mesa_printf("."); - if (dst->WriteMask[0]) - _mesa_printf("x"); - if (dst->WriteMask[1]) - _mesa_printf("y"); - if (dst->WriteMask[2]) - _mesa_printf("z"); - if (dst->WriteMask[3]) - _mesa_printf("w"); - } -} - - -/** - * Print a single NVIDIA vertex program instruction. - */ -void -_mesa_print_nv_vertex_instruction(const struct vp_instruction *inst) -{ - 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]); - 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]); - _mesa_printf(";\n"); - break; - case VP_OPCODE_ARL: - _mesa_printf("ARL A0.x, "); - PrintSrcReg(&inst->SrcReg[0]); - _mesa_printf(";\n"); - break; - case VP_OPCODE_END: - _mesa_printf("END\n"); - break; - default: - _mesa_printf("BAD INSTRUCTION\n"); - } -} - - -/** - * Print (unparse) the given vertex program. Just for debugging. - */ -void -_mesa_print_nv_vertex_program(const struct vertex_program *program) -{ - const struct vp_instruction *inst; - - for (inst = program->Instructions; ; inst++) { - _mesa_print_nv_vertex_instruction(inst); - if (inst->Opcode == VP_OPCODE_END) - return; - } -} - - const char * _mesa_nv_vertex_input_register_name(GLuint i) { @@ -1496,3 +1425,4 @@ _mesa_nv_vertex_output_register_name(GLuint i) ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS); return OutputRegisters[i]; } +