📄 nvvertparse.c
字号:
/* try to match an output register name */ for (j = start; OutputRegisters[j]; j++) { if (_mesa_strcmp((const char *) token, OutputRegisters[j]) == 0) { *outputRegNum = j; break; } } if (!OutputRegisters[j]) RETURN_ERROR1("Unrecognized output register name"); /* Match ']' */ if (!Parse_String(parseState, "]")) RETURN_ERROR1("Expected ]"); return GL_TRUE;}static GLbooleanParse_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)) RETURN_ERROR; if (token[0] == 'R') { /* a temporary register */ dstReg->File = PROGRAM_TEMPORARY; 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, &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, &idx)) RETURN_ERROR; dstReg->Index = idx; } else { RETURN_ERROR1("Bad destination register name"); } /* Parse optional write mask */ if (!Peek_Token(parseState, token)) RETURN_ERROR; if (token[0] == '.') { /* got a mask */ GLint k = 0; if (!Parse_String(parseState, ".")) RETURN_ERROR; if (!Parse_Token(parseState, token)) RETURN_ERROR; dstReg->WriteMask = 0; if (token[k] == 'x') { dstReg->WriteMask |= WRITEMASK_X; k++; } if (token[k] == 'y') { dstReg->WriteMask |= WRITEMASK_Y; k++; } if (token[k] == 'z') { dstReg->WriteMask |= WRITEMASK_Z; k++; } if (token[k] == 'w') { dstReg->WriteMask |= WRITEMASK_W; k++; } if (k == 0) { RETURN_ERROR1("Bad writemask character"); } return GL_TRUE; } else { dstReg->WriteMask = WRITEMASK_XYZW; return GL_TRUE; }}static GLbooleanParse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg){ GLubyte token[100]; GLint idx; srcReg->RelAddr = GL_FALSE; /* check for '-' */ if (!Peek_Token(parseState, token)) RETURN_ERROR; if (token[0] == '-') { (void) Parse_String(parseState, "-"); srcReg->NegateBase = NEGATE_XYZW; if (!Peek_Token(parseState, token)) RETURN_ERROR; } else { 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, &idx)) RETURN_ERROR; srcReg->Index = idx; } else if (token[0] == 'c') { 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 { RETURN_ERROR2("Bad source register name", token); } /* init swizzle fields */ srcReg->Swizzle = SWIZZLE_NOOP; /* Look for optional swizzle suffix */ if (!Peek_Token(parseState, token)) RETURN_ERROR; if (token[0] == '.') { (void) Parse_String(parseState, "."); /* consume . */ if (!Parse_Token(parseState, token)) RETURN_ERROR; if (token[1] == 0) { /* single letter swizzle */ if (token[0] == 'x') srcReg->Swizzle = SWIZZLE_XXXX; else if (token[0] == 'y') srcReg->Swizzle = SWIZZLE_YYYY; else if (token[0] == 'z') srcReg->Swizzle = SWIZZLE_ZZZZ; else if (token[0] == 'w') 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 |= 0 << (k*3); else if (token[k] == 'y') srcReg->Swizzle |= 1 << (k*3); else if (token[k] == 'z') srcReg->Swizzle |= 2 << (k*3); else if (token[k] == 'w') srcReg->Swizzle |= 3 << (k*3); else RETURN_ERROR; } if (k >= 5) RETURN_ERROR; } } return GL_TRUE;}static GLbooleanParse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg){ GLubyte token[100]; GLint idx; srcReg->RelAddr = GL_FALSE; /* check for '-' */ if (!Peek_Token(parseState, token)) RETURN_ERROR; if (token[0] == '-') { srcReg->NegateBase = NEGATE_XYZW; (void) Parse_String(parseState, "-"); /* consume '-' */ if (!Peek_Token(parseState, token)) RETURN_ERROR; } else { 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, &idx)) RETURN_ERROR; srcReg->Index = idx; } else if (token[0] == 'c') { 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 { RETURN_ERROR2("Bad source register name", token); } /* Look for .[xyzw] suffix */ if (!Parse_String(parseState, ".")) RETURN_ERROR; if (!Parse_Token(parseState, token)) RETURN_ERROR; if (token[0] == 'x' && token[1] == 0) { srcReg->Swizzle = 0; } else if (token[0] == 'y' && token[1] == 0) { srcReg->Swizzle = 1; } else if (token[0] == 'z' && token[1] == 0) { srcReg->Swizzle = 2; } else if (token[0] == 'w' && token[1] == 0) { srcReg->Swizzle = 3; } else { RETURN_ERROR1("Bad scalar source suffix"); } return GL_TRUE;}static GLintParse_UnaryOpInstruction(struct parse_state *parseState, struct prog_instruction *inst, enum prog_opcode opcode){ 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)) RETURN_ERROR; /* comma */ if (!Parse_String(parseState, ",")) RETURN_ERROR; /* src arg */ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) RETURN_ERROR; /* semicolon */ if (!Parse_String(parseState, ";")) RETURN_ERROR; return GL_TRUE;}static GLbooleanParse_BiOpInstruction(struct parse_state *parseState, struct prog_instruction *inst, enum prog_opcode opcode){ if (opcode == OPCODE_DPH && !parseState->isVersion1_1) RETURN_ERROR1("DPH illegal for vertex program 1.0"); 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)) RETURN_ERROR; /* comma */ if (!Parse_String(parseState, ",")) RETURN_ERROR; /* first src arg */ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) RETURN_ERROR; /* comma */ if (!Parse_String(parseState, ",")) RETURN_ERROR; /* second src arg */ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1])) RETURN_ERROR; /* semicolon */ if (!Parse_String(parseState, ";")) RETURN_ERROR; /* make sure we don't reference more than one program parameter register */ if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM && inst->SrcReg[1].File == PROGRAM_ENV_PARAM && inst->SrcReg[0].Index != inst->SrcReg[1].Index) RETURN_ERROR1("Can't reference two program parameter registers"); /* make sure we don't reference more than one vertex attribute register */ if (inst->SrcReg[0].File == PROGRAM_INPUT && inst->SrcReg[1].File == PROGRAM_INPUT && inst->SrcReg[0].Index != inst->SrcReg[1].Index) RETURN_ERROR1("Can't reference two vertex attribute registers"); return GL_TRUE;}static GLbooleanParse_TriOpInstruction(struct parse_state *parseState, 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)) RETURN_ERROR; /* comma */ if (!Parse_String(parseState, ",")) RETURN_ERROR; /* first src arg */ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0])) RETURN_ERROR; /* comma */ if (!Parse_String(parseState, ",")) RETURN_ERROR; /* second src arg */ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1])) RETURN_ERROR; /* comma */ if (!Parse_String(parseState, ",")) RETURN_ERROR; /* third src arg */ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2])) RETURN_ERROR; /* semicolon */ if (!Parse_String(parseState, ";")) RETURN_ERROR; /* make sure we don't reference more than one program parameter register */ if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM && inst->SrcReg[1].File == PROGRAM_ENV_PARAM && inst->SrcReg[0].Index != inst->SrcReg[1].Index) || (inst->SrcReg[0].File == PROGRAM_ENV_PARAM && inst->SrcReg[2].File == PROGRAM_ENV_PARAM && inst->SrcReg[0].Index != inst->SrcReg[2].Index) || (inst->SrcReg[1].File == PROGRAM_ENV_PARAM && inst->SrcReg[2].File == PROGRAM_ENV_PARAM && inst->SrcReg[1].Index != inst->SrcReg[2].Index)) RETURN_ERROR1("Can only reference one program register"); /* make sure we don't reference more than one vertex attribute register */ if ((inst->SrcReg[0].File == PROGRAM_INPUT && inst->SrcReg[1].File == PROGRAM_INPUT && inst->SrcReg[0].Index != inst->SrcReg[1].Index) || (inst->SrcReg[0].File == PROGRAM_INPUT && inst->SrcReg[2].File == PROGRAM_INPUT && inst->SrcReg[0].Index != inst->SrcReg[2].Index) || (inst->SrcReg[1].File == PROGRAM_INPUT && inst->SrcReg[2].File == PROGRAM_INPUT && inst->SrcReg[1].Index != inst->SrcReg[2].Index)) RETURN_ERROR1("Can only reference one input register"); return GL_TRUE;}static GLbooleanParse_ScalarInstruction(struct parse_state *parseState, struct prog_instruction *inst, enum prog_opcode opcode){ 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)) RETURN_ERROR; /* comma */ if (!Parse_String(parseState, ",")) RETURN_ERROR; /* first src arg */ if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) RETURN_ERROR; /* semicolon */ if (!Parse_String(parseState, ";")) RETURN_ERROR; return GL_TRUE;}static GLbooleanParse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst){ 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; /* comma */ if (!Parse_String(parseState, ",")) RETURN_ERROR; /* parse src reg */ if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0])) RETURN_ERROR; /* semicolon */ if (!Parse_String(parseState, ";")) RETURN_ERROR; return GL_TRUE;}static GLbooleanParse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst){ GLubyte token[100]; inst->Opcode = OPCODE_END; inst->StringPos = parseState->curLine - parseState->start; /* this should fail! */ if (Parse_Token(parseState, token)) RETURN_ERROR2("Unexpected token after END:", token); else return GL_TRUE;}/** * 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 GLbooleanParse_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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -