📄 nvfragparse.c
字号:
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("Invalid writemask character");
}
}
else {
dstReg->WriteMask = WRITEMASK_XYZW;
}
/* optional condition code mask */
if (Parse_String(parseState, "(")) {
/* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".x|y|z|w) */
/* ("EQ" | "GE" | "GT" | "LE" | "LT" | "NE" | "TR" | "FL".[xyzw]) */
if (!Parse_CondCodeMask(parseState, dstReg))
RETURN_ERROR;
if (!Parse_String(parseState, ")")) /* consume ")" */
RETURN_ERROR1("Expected )");
return GL_TRUE;
}
else {
/* no cond code mask */
dstReg->CondMask = COND_TR;
dstReg->CondSwizzle = SWIZZLE_NOOP;
return GL_TRUE;
}
}
/**
* Parse a vector source (register, constant, etc):
* <vectorSrc> ::= <absVectorSrc>
* | <baseVectorSrc>
* <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|"
*/
static GLboolean
Parse_VectorSrc(struct parse_state *parseState,
struct fp_src_register *srcReg)
{
GLfloat sign = 1.0F;
GLubyte token[100];
GLint idx;
/*
* First, take care of +/- and absolute value stuff.
*/
if (Parse_String(parseState, "-"))
sign = -1.0F;
else if (Parse_String(parseState, "+"))
sign = +1.0F;
if (Parse_String(parseState, "|")) {
srcReg->Abs = GL_TRUE;
srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
if (Parse_String(parseState, "-"))
srcReg->NegateBase = GL_TRUE;
else if (Parse_String(parseState, "+"))
srcReg->NegateBase = GL_FALSE;
else
srcReg->NegateBase = GL_FALSE;
}
else {
srcReg->Abs = GL_FALSE;
srcReg->NegateAbs = GL_FALSE;
srcReg->NegateBase = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
}
/* This should be the real src vector/register name */
if (!Peek_Token(parseState, token))
RETURN_ERROR;
/* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar
* literal or vector literal.
*/
if (token[0] == 'R' || token[0] == 'H') {
srcReg->File = PROGRAM_TEMPORARY;
if (!Parse_TempReg(parseState, &idx))
RETURN_ERROR;
srcReg->Index = idx;
}
else if (token[0] == 'f') {
/* XXX this might be an identier! */
srcReg->File = PROGRAM_INPUT;
if (!Parse_FragReg(parseState, &idx))
RETURN_ERROR;
srcReg->Index = idx;
}
else if (token[0] == 'p') {
/* XXX this might be an identier! */
srcReg->File = PROGRAM_LOCAL_PARAM;
if (!Parse_ProgramParamReg(parseState, &idx))
RETURN_ERROR;
srcReg->Index = idx;
}
else if (IsLetter(token[0])){
GLubyte ident[100];
GLint paramIndex;
if (!Parse_Identifier(parseState, ident))
RETURN_ERROR;
paramIndex = _mesa_lookup_parameter_index(parseState->parameters,
-1, (const char *) ident);
if (paramIndex < 0) {
RETURN_ERROR2("Undefined constant or parameter: ", ident);
}
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){
/* literal scalar constant */
GLfloat values[4];
GLuint paramIndex;
if (!Parse_ScalarConstant(parseState, values))
RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
else if (token[0] == '{'){
/* literal vector constant */
GLfloat values[4];
GLuint paramIndex;
(void) Parse_String(parseState, "{");
if (!Parse_VectorConstant(parseState, values))
RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
else {
RETURN_ERROR2("Invalid source register name", token);
}
/* init swizzle fields */
srcReg->Swizzle = SWIZZLE_NOOP;
/* Look for optional swizzle suffix */
if (Parse_String(parseState, ".")) {
GLuint swz[4];
if (!Parse_Token(parseState, token))
RETURN_ERROR;
if (!Parse_SwizzleSuffix(token, swz))
RETURN_ERROR1("Invalid swizzle suffix");
srcReg->Swizzle = MAKE_SWIZZLE(swz);
}
/* Finish absolute value */
if (srcReg->Abs && !Parse_String(parseState, "|")) {
RETURN_ERROR1("Expected |");
}
return GL_TRUE;
}
static GLboolean
Parse_ScalarSrcReg(struct parse_state *parseState,
struct fp_src_register *srcReg)
{
GLubyte token[100];
GLfloat sign = 1.0F;
GLboolean needSuffix = GL_TRUE;
GLint idx;
/*
* First, take care of +/- and absolute value stuff.
*/
if (Parse_String(parseState, "-"))
sign = -1.0F;
else if (Parse_String(parseState, "+"))
sign = +1.0F;
if (Parse_String(parseState, "|")) {
srcReg->Abs = GL_TRUE;
srcReg->NegateAbs = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
if (Parse_String(parseState, "-"))
srcReg->NegateBase = GL_TRUE;
else if (Parse_String(parseState, "+"))
srcReg->NegateBase = GL_FALSE;
else
srcReg->NegateBase = GL_FALSE;
}
else {
srcReg->Abs = GL_FALSE;
srcReg->NegateAbs = GL_FALSE;
srcReg->NegateBase = (sign < 0.0F) ? GL_TRUE : GL_FALSE;
}
if (!Peek_Token(parseState, token))
RETURN_ERROR;
/* Src reg can be R<n>, H<n> or a named fragment attrib */
if (token[0] == 'R' || token[0] == 'H') {
srcReg->File = PROGRAM_TEMPORARY;
if (!Parse_TempReg(parseState, &idx))
RETURN_ERROR;
srcReg->Index = idx;
}
else if (token[0] == 'f') {
srcReg->File = PROGRAM_INPUT;
if (!Parse_FragReg(parseState, &idx))
RETURN_ERROR;
srcReg->Index = idx;
}
else if (token[0] == '{') {
/* vector literal */
GLfloat values[4];
GLuint paramIndex;
(void) Parse_String(parseState, "{");
if (!Parse_VectorConstant(parseState, values))
RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
srcReg->File = PROGRAM_NAMED_PARAM;
srcReg->Index = paramIndex;
}
else if (IsDigit(token[0])) {
/* scalar literal */
GLfloat values[4];
GLuint paramIndex;
if (!Parse_ScalarConstant(parseState, values))
RETURN_ERROR;
paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values);
srcReg->Index = paramIndex;
srcReg->File = PROGRAM_NAMED_PARAM;
needSuffix = GL_FALSE;
}
else {
RETURN_ERROR2("Invalid scalar source argument", token);
}
srcReg->Swizzle = 0;
if (needSuffix) {
/* parse .[xyzw] suffix */
if (!Parse_String(parseState, "."))
RETURN_ERROR1("Expected .");
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("Invalid scalar source suffix");
}
}
/* Finish absolute value */
if (srcReg->Abs && !Parse_String(parseState, "|")) {
RETURN_ERROR1("Expected |");
}
return GL_TRUE;
}
static GLboolean
Parse_PrintInstruction(struct parse_state *parseState,
struct fp_instruction *inst)
{
const GLubyte *str;
GLubyte *msg;
GLuint len;
GLint idx;
/* The first argument is a literal string 'just like this' */
if (!Parse_String(parseState, "'"))
RETURN_ERROR1("Expected '");
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;
if (Parse_String(parseState, ",")) {
/* got an optional register to print */
GLubyte token[100];
GetToken(parseState, token);
if (token[0] == 'o') {
/* dst reg */
if (!Parse_OutputReg(parseState, &idx))
RETURN_ERROR;
inst->SrcReg[0].Index = idx;
inst->SrcReg[0].File = PROGRAM_OUTPUT;
}
else {
/* src reg */
if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
RETURN_ERROR;
}
}
else {
/* File = 0 indicates no register to print */
inst->SrcReg[0].File = PROGRAM_UNDEFINED;
}
inst->SrcReg[0].Swizzle = SWIZZLE_NOOP;
inst->SrcReg[0].NegateBase = GL_FALSE;
inst->SrcReg[0].Abs = GL_FALSE;
inst->SrcReg[0].NegateAbs = GL_FALSE;
return GL_TRUE;
}
static GLboolean
Parse_InstructionSequence(struct parse_state *parseState,
struct fp_instruction program[])
{
while (1) {
struct fp_instruction *inst = program + parseState->numInst;
struct instruction_pattern instMatch;
GLubyte token[100];
/* Initialize the instruction */
inst->SrcReg[0].File = PROGRAM_UNDEFINED;
inst->SrcReg[1].File = PROGRAM_UNDEFINED;
inst->SrcReg[2].File = PROGRAM_UNDEFINED;
inst->DstReg.File = PROGRAM_UNDEFINED;
inst->DstReg.CondSwizzle = SWIZZLE_NOOP;
inst->Data = NULL;
/* special instructions */
if (Parse_String(parseState, "DEFINE")) {
GLubyte id[100];
GLfloat value[7]; /* yes, 7 to be safe */
if (!Parse_Identifier(parseState, id))
RETURN_ERROR;
/* XXX make sure id is not a reserved identifer, like R9 */
if (!Parse_String(parseState, "="))
RETURN_ERROR1("Expected =");
if (!Parse_VectorOrScalarConstant(parseState, value))
RETURN_ERROR;
if (!Parse_String(parseState, ";"))
RETURN_ERROR1("Expected ;");
if (_mesa_lookup_parameter_index(parseState->parameters,
-1, (const char *) id) >= 0) {
RETURN_ERROR2(id, "already defined");
}
_mesa_add_named_parameter(parseState->parameters,
(const char *) id, value);
}
else if (Parse_String(parseState, "DECLARE")) {
GLubyte id[100];
GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0}; /* yes, to be safe */
if (!Parse_Identifier(parseState, id))
RETURN_ERROR;
/* XXX make sure id is not a reserved identifer, like R9 */
if (Parse_String(parseState, "=")) {
if (!Parse_VectorOrScalarConstant(parseState, value))
RETURN_ERROR;
}
if (!Parse_String(parseState, ";"))
RETURN_ERROR1("Expected ;");
if (_mesa_lookup_parameter_index(parseState->parameters,
-1, (const char *) id) >= 0) {
RETURN_ERROR2(id, "already declared");
}
_mesa_add_named_parameter(parseState->parameters,
(const char *) id, value);
}
else if (Parse_String(parseState, "END")) {
inst->Opcode = FP_OPCODE_END;
inst->StringPos = parseState->curLine - parseState->start;
assert(inst->StringPos >= 0);
parseState->numInst++;
if (Parse_Token(parseState, token)) {
RETURN_ERROR1("Code after END opcode.");
}
break;
}
else {
/* general/arithmetic instruction */
/* get token */
if (!Parse_Token(parseState, token)) {
RETURN_ERROR1("Missing END instruction.");
}
/* try to find matching instuction */
instMatch = MatchInstruction(token);
if (instMatch.opcode < 0) {
/* bad instruction name */
RETURN_ERROR2("Unexpected token: ", token);
}
inst->Opcode = instMatch.opcode;
inst->Precision = instMatch.suffixes & (_R | _H | _X);
inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE;
inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE;
inst->StringPos = parseState->curLine - parseState->start;
assert(inst->StringPos >= 0);
/*
* parse the input and output operands
*/
if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) {
if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
RETURN_ERROR;
if (!Parse_String(parseState, ","))
RETURN_ERROR1("Expected ,");
}
else if (instMatch.outputs == OUTPUT_NONE) {
if (instMatch.opcode == FP_OPCODE_KIL_NV) {
/* This is a little weird, the cond code info is in
* the dest register.
*/
if (!Parse_CondCodeMask(parseState, &inst->DstReg))
RETURN_ERROR;
}
else {
ASSERT(instMatch.opcode == FP_OPCODE_PRINT);
}
}
if (instMatch.inputs == INPUT_1V) {
if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
RETURN_ERROR;
}
else if (instMatch.inputs == INPUT_2V) {
if (!Parse_VectorSrc(parseState, &inst->SrcReg[0]))
RETURN_ERROR;
if (!Parse_String(parseState, ","))
RETURN_ERROR1("Expected ,");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -