📄 nvvertparse.c
字号:
if (!Parse_Token(parseState, token))
RETURN_ERROR;
if (parseState->isPositionInvariant)
start = 1; /* skip HPOS register name */
else
start = 0;
/* 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 GLboolean
Parse_MaskedDstReg(struct parse_state *parseState, struct vp_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 GLboolean
Parse_SwizzleSrcReg(struct parse_state *parseState, struct vp_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->Negate = GL_TRUE;
if (!Peek_Token(parseState, token))
RETURN_ERROR;
}
else {
srcReg->Negate = GL_FALSE;
}
/* 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 = MAKE_SWIZZLE4(0, 0, 0, 0);
else if (token[0] == 'y')
srcReg->Swizzle = MAKE_SWIZZLE4(1, 1, 1, 1);
else if (token[0] == 'z')
srcReg->Swizzle = MAKE_SWIZZLE4(2, 2, 2, 2);
else if (token[0] == 'w')
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;
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 GLboolean
Parse_ScalarSrcReg(struct parse_state *parseState, struct vp_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->Negate = GL_TRUE;
(void) Parse_String(parseState, "-"); /* consume '-' */
if (!Peek_Token(parseState, token))
RETURN_ERROR;
}
else {
srcReg->Negate = GL_FALSE;
}
/* 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 GLint
Parse_UnaryOpInstruction(struct parse_state *parseState,
struct vp_instruction *inst, enum vp_opcode opcode)
{
if (opcode == VP_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 GLboolean
Parse_BiOpInstruction(struct parse_state *parseState,
struct vp_instruction *inst, enum vp_opcode opcode)
{
if (opcode == VP_OPCODE_DPH && !parseState->isVersion1_1)
RETURN_ERROR1("DPH illegal for vertex program 1.0");
if (opcode == VP_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 GLboolean
Parse_TriOpInstruction(struct parse_state *parseState,
struct vp_instruction *inst, enum vp_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 GLboolean
Parse_ScalarInstruction(struct parse_state *parseState,
struct vp_instruction *inst, enum vp_opcode opcode)
{
if (opcode == VP_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 GLboolean
Parse_AddressInstruction(struct parse_state *parseState, struct vp_instruction *inst)
{
inst->Opcode = VP_OPCODE_ARL;
inst->StringPos = parseState->curLine - parseState->start;
/* 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 GLboolean
Parse_EndInstruction(struct parse_state *parseState, struct vp_instruction *inst)
{
GLubyte token[100];
inst->Opcode = VP_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 GLboolean
Parse_PrintInstruction(struct parse_state *parseState, struct vp_instruction *inst)
{
const GLubyte *str;
GLubyte *msg;
GLuint len;
GLubyte token[100];
struct vp_src_register *srcReg = &inst->SrcReg[0];
GLint idx;
inst->Opcode = VP_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 = _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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -