From: Brian Paul Date: Mon, 17 Feb 2003 15:38:03 +0000 (+0000) Subject: Implement parsing of texture instructions and prototype execution. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=04cbad84e8241ced16f146e36b6959e4c78cfac1;p=mesa.git Implement parsing of texture instructions and prototype execution. Misc parser clean-ups. --- diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c index 7b9208d5211..45ff45dcec0 100644 --- a/src/mesa/main/nvfragparse.c +++ b/src/mesa/main/nvfragparse.c @@ -1,4 +1,4 @@ -/* $Id: nvfragparse.c,v 1.4 2003/02/16 23:07:35 brianp Exp $ */ +/* $Id: nvfragparse.c,v 1.5 2003/02/17 15:38:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -127,9 +127,9 @@ static const struct instruction_pattern Instructions[] = { { "SNE", FP_OPCODE_SNE, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, { "STR", FP_OPCODE_STR, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, { "SUB", FP_OPCODE_SUB, INPUT_2V, OUTPUT_V, _R | _H | _X | _C | _S }, - { "TEX", FP_OPCODE_SUB, INPUT_1V_T, OUTPUT_V, _C | _S }, - { "TXD", FP_OPCODE_SUB, INPUT_3V_T, OUTPUT_V, _C | _S }, - { "TXP", FP_OPCODE_SUB, INPUT_1V_T, OUTPUT_V, _C | _S }, + { "TEX", FP_OPCODE_TEX, INPUT_1V_T, OUTPUT_V, _C | _S }, + { "TXD", FP_OPCODE_TXD, INPUT_3V_T, OUTPUT_V, _C | _S }, + { "TXP", FP_OPCODE_TXP, INPUT_1V_T, OUTPUT_V, _C | _S }, { "UP2H", FP_OPCODE_UP2H, INPUT_1S, OUTPUT_V, _C | _S }, { "UP2US", FP_OPCODE_UP2US, INPUT_1S, OUTPUT_V, _C | _S }, { "UP4B", FP_OPCODE_UP4B, INPUT_1S, OUTPUT_V, _C | _S }, @@ -349,29 +349,29 @@ static const char *OutputRegisters[] = { #ifdef DEBUG -#define PARSE_ERROR \ +#define RETURN_ERROR \ do { \ - _mesa_printf("fpparse.c error at %d: parse error\n", __LINE__); \ + _mesa_printf("nvfragparse.c error at %d: parse error\n", __LINE__); \ return GL_FALSE; \ } while(0) -#define PARSE_ERROR1(msg) \ +#define RETURN_ERROR1(msg) \ do { \ - _mesa_printf("fpparse.c error at %d: %s\n", __LINE__, msg); \ + _mesa_printf("nvfragparse.c error at %d: %s\n", __LINE__, msg); \ return GL_FALSE; \ } while(0) -#define PARSE_ERROR2(msg1, msg2) \ +#define RETURN_ERROR2(msg1, msg2) \ do { \ - _mesa_printf("fpparse.c error at %d: %s %s\n", __LINE__, msg1, msg2);\ + _mesa_printf("nvfragparse.c error at %d: %s %s\n", __LINE__, msg1, msg2);\ return GL_FALSE; \ } while(0) #else -#define PARSE_ERROR return GL_FALSE -#define PARSE_ERROR1(msg1) return GL_FALSE -#define PARSE_ERROR2(msg1, msg2) return GL_FALSE +#define RETURN_ERROR return GL_FALSE +#define RETURN_ERROR1(msg1) return GL_FALSE +#define RETURN_ERROR2(msg1, msg2) return GL_FALSE #endif @@ -441,6 +441,7 @@ DummyRegisterNumber(GLuint r) static GLboolean Parse_String(const char **s, const char *pattern) { + const char *m; GLint i; /* skip whitespace and comments */ @@ -457,11 +458,13 @@ Parse_String(const char **s, const char *pattern) } /* Try to match the pattern */ + m = *s; for (i = 0; pattern[i]; i++) { - if (**s != pattern[i]) - PARSE_ERROR2("failed to match", pattern); /* failure */ - *s += 1; + if (*m != pattern[i]) + return GL_FALSE; + m += 1; } + *s = m; return GL_TRUE; /* success */ } @@ -471,11 +474,11 @@ static GLboolean Parse_Identifier(const char **s, char *ident) { if (!Parse_Token(s, ident)) - PARSE_ERROR; + RETURN_ERROR; if (IsLetter(ident[0])) return GL_TRUE; else - PARSE_ERROR1("Expected an identfier"); + RETURN_ERROR1("Expected an identfier"); } @@ -499,9 +502,9 @@ Parse_ScalarConstant(const char **s, GLfloat *number) /* should be an identifier */ char ident[100]; if (!Parse_Identifier(s, ident)) - PARSE_ERROR1("Expected an identifier"); + RETURN_ERROR1("Expected an identifier"); if (!_mesa_lookup_symbol(&(CurrentProgram->SymbolTable), ident, number)) { - PARSE_ERROR1("Undefined symbol"); + RETURN_ERROR1("Undefined symbol"); } return GL_TRUE; } @@ -522,7 +525,7 @@ Parse_VectorConstant(const char **s, GLfloat *vec) char token[100]; if (!Parse_String(s, "{")) - return GL_FALSE; + RETURN_ERROR1("Expected {"); if (!Parse_ScalarConstant(s, vec+0)) /* X */ return GL_FALSE; @@ -536,7 +539,7 @@ Parse_VectorConstant(const char **s, GLfloat *vec) } if (token[0] != ',') - PARSE_ERROR1("Expected comma in vector constant"); + RETURN_ERROR1("Expected comma in vector constant"); if (!Parse_ScalarConstant(s, vec+1)) /* Y */ return GL_FALSE; @@ -550,7 +553,7 @@ Parse_VectorConstant(const char **s, GLfloat *vec) } if (token[0] != ',') - PARSE_ERROR1("Expected comma in vector constant"); + RETURN_ERROR1("Expected comma in vector constant"); if (!Parse_ScalarConstant(s, vec+2)) /* Z */ return GL_FALSE; @@ -564,13 +567,13 @@ Parse_VectorConstant(const char **s, GLfloat *vec) } if (token[0] != ',') - PARSE_ERROR1("Expected comma in vector constant"); + RETURN_ERROR1("Expected comma in vector constant"); if (!Parse_ScalarConstant(s, vec+3)) /* W */ return GL_FALSE; if (!Parse_String(s, "}")) - PARSE_ERROR1("Expected closing brace in vector constant"); + RETURN_ERROR1("Expected closing brace in vector constant"); return GL_TRUE; } @@ -585,7 +588,7 @@ Parse_VectorOrScalarConstant(const char **s, GLfloat *vec) { char token[100]; if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] == '{') { return Parse_VectorConstant(s, vec); } @@ -601,12 +604,50 @@ Parse_VectorOrScalarConstant(const char **s, GLfloat *vec) /** * Parse a texture image source: - * [TEX0 | TEX1 | .. | TEX15] - * [TEX0 | TEX1 | .. | TEX15] . [1D | 2D | 3D | CUBE | RECT] + * [TEX0 | TEX1 | .. | TEX15] , [1D | 2D | 3D | CUBE | RECT] */ static GLboolean -Parse_TextureImageId(const char **s, GLuint *unit, GLenum *target) +Parse_TextureImageId(const char **s, GLuint *texUnit, GLenum *texTarget) { + char imageSrc[100]; + GLint unit; + + if (!Parse_Token(s, imageSrc)) + RETURN_ERROR; + + if (imageSrc[0] != 'T' || + imageSrc[1] != 'E' || + imageSrc[2] != 'X') { + RETURN_ERROR1("Expected TEX# source"); + } + unit = _mesa_atoi(imageSrc + 3); + if ((unit < 0 || unit > MAX_TEXTURE_IMAGE_UNITS) || + (unit == 0 && (imageSrc[3] != '0' || imageSrc[4] != 0))) { + RETURN_ERROR1("Invalied TEX# source index"); + } + *texUnit = unit; + + if (!Parse_String(s, ",")) + RETURN_ERROR1("Expected ,"); + + if (Parse_String(s, "1D")) { + *texTarget = GL_TEXTURE_1D; + } + else if (Parse_String(s, "2D")) { + *texTarget = GL_TEXTURE_2D; + } + else if (Parse_String(s, "3D")) { + *texTarget = GL_TEXTURE_3D; + } + else if (Parse_String(s, "CUBE")) { + *texTarget = GL_TEXTURE_CUBE_MAP; + } + else if (Parse_String(s, "RECT")) { + *texTarget = GL_TEXTURE_RECTANGLE_NV; + } + else { + RETURN_ERROR1("Invalid texture target token"); + } return GL_TRUE; } @@ -659,7 +700,7 @@ Parse_CondCodeMask(const char **s, struct fp_dst_register *dstReg) char token[100]; if (!Parse_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (StrEq(token, "EQ")) dstReg->CondMask = COND_EQ; @@ -678,19 +719,19 @@ Parse_CondCodeMask(const char **s, struct fp_dst_register *dstReg) else if (StrEq(token, "FL")) dstReg->CondMask = COND_FL; else - PARSE_ERROR1("Invalid condition code mask"); + RETURN_ERROR1("Invalid condition code mask"); /* look for optional .xyzw swizzle */ if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] == '.') { Parse_String(s, "."); /* consume '.' */ if (!Parse_Token(s, token)) /* get xyzw suffix */ - PARSE_ERROR; + RETURN_ERROR; if (!Parse_SwizzleSuffix(token, dstReg->CondSwizzle)) - PARSE_ERROR1("Bad swizzle suffix"); + RETURN_ERROR1("Bad swizzle suffix"); } return GL_TRUE; @@ -707,20 +748,20 @@ Parse_TempReg(const char **s, GLint *tempRegNum) /* Should be 'R##' or 'H##' */ if (!Parse_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] != 'R' && token[0] != 'H') - PARSE_ERROR1("Expected R## or H##"); + RETURN_ERROR1("Expected R## or H##"); if (IsDigit(token[1])) { GLint reg = _mesa_atoi((token + 1)); if (token[0] == 'H') reg += 32; if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS) - PARSE_ERROR1("Bad temporary register name"); + RETURN_ERROR1("Bad temporary register name"); *tempRegNum = FP_TEMP_REG_START + reg; } else { - PARSE_ERROR1("Bad temporary register name"); + RETURN_ERROR1("Bad temporary register name"); } return GL_TRUE; @@ -734,7 +775,7 @@ Parse_DummyReg(const char **s, GLint *regNum) /* Should be 'RC' or 'HC' */ if (!Parse_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (_mesa_strcmp(token, "RC")) { *regNum = FP_DUMMY_REG_START; @@ -743,7 +784,7 @@ Parse_DummyReg(const char **s, GLint *regNum) *regNum = FP_DUMMY_REG_START + 1; } else { - PARSE_ERROR1("Bad write-only register name"); + RETURN_ERROR1("Bad write-only register name"); } return GL_TRUE; @@ -759,27 +800,27 @@ Parse_ProgramParamReg(const char **s, GLint *regNum) char token[100]; if (!Parse_String(s, "p")) - PARSE_ERROR; + RETURN_ERROR1("Expected p"); if (!Parse_String(s, "[")) - PARSE_ERROR; + RETURN_ERROR1("Expected ["); if (!Parse_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (IsDigit(token[0])) { /* a numbered program parameter register */ GLint reg = _mesa_atoi(token); if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS) - PARSE_ERROR1("Bad constant program number"); + RETURN_ERROR1("Bad constant program number"); *regNum = FP_PROG_REG_START + reg; } else { - PARSE_ERROR; + RETURN_ERROR; } if (!Parse_String(s, "]")) - PARSE_ERROR; + RETURN_ERROR1("Expected ]"); return GL_TRUE; } @@ -796,15 +837,15 @@ Parse_AttribReg(const char **s, GLint *tempRegNum) /* Match 'f' */ if (!Parse_String(s, "f")) - PARSE_ERROR; + RETURN_ERROR1("Expected f"); /* Match '[' */ if (!Parse_String(s, "[")) - PARSE_ERROR; + RETURN_ERROR1("Expected ["); /* get and look for match */ if (!Parse_Token(s, token)) { - PARSE_ERROR; + RETURN_ERROR; } for (j = 0; InputRegisters[j]; j++) { if (StrEq(token, InputRegisters[j])) { @@ -814,12 +855,12 @@ Parse_AttribReg(const char **s, GLint *tempRegNum) } if (!InputRegisters[j]) { /* unknown input register label */ - PARSE_ERROR2("Bad register name", token); + RETURN_ERROR2("Bad register name", token); } /* Match '[' */ if (!Parse_String(s, "]")) - PARSE_ERROR; + RETURN_ERROR1("Expected ]"); return GL_TRUE; } @@ -831,17 +872,13 @@ Parse_OutputReg(const char **s, GLint *outputRegNum) char token[100]; GLint j; - /* Match 'o' */ - if (!Parse_String(s, "o")) - PARSE_ERROR; - - /* Match '[' */ - if (!Parse_String(s, "[")) - PARSE_ERROR; + /* Match "o[" */ + if (!Parse_String(s, "o[")) + RETURN_ERROR1("Expected o["); /* Get output reg name */ if (!Parse_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; /* try to match an output register name */ for (j = 0; OutputRegisters[j]; j++) { @@ -851,11 +888,11 @@ Parse_OutputReg(const char **s, GLint *outputRegNum) } } if (!OutputRegisters[j]) - PARSE_ERROR1("Unrecognized output register name"); + RETURN_ERROR1("Unrecognized output register name"); /* Match ']' */ if (!Parse_String(s, "]")) - PARSE_ERROR1("Expected ]"); + RETURN_ERROR1("Expected ]"); return GL_TRUE; } @@ -868,41 +905,41 @@ Parse_MaskedDstReg(const char **s, struct fp_dst_register *dstReg) /* Dst reg can be R, H, o[n], RC or HC */ if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (_mesa_strcmp(token, "RC") == 0 || _mesa_strcmp(token, "HC") == 0) { /* a write-only register */ if (!Parse_DummyReg(s, &dstReg->Register)) - PARSE_ERROR; + RETURN_ERROR; } else if (token[0] == 'R' || token[0] == 'H') { /* a temporary register */ if (!Parse_TempReg(s, &dstReg->Register)) - PARSE_ERROR; + RETURN_ERROR; } else if (token[0] == 'o') { /* an output register */ if (!Parse_OutputReg(s, &dstReg->Register)) - PARSE_ERROR; + RETURN_ERROR; } else { - PARSE_ERROR1("Bad destination register name"); + RETURN_ERROR1("Bad destination register name"); } /* Parse optional write mask */ if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] == '.') { /* got a mask */ GLint k = 0; if (!Parse_String(s, ".")) - PARSE_ERROR; + RETURN_ERROR1("Expected ."); if (!Parse_Token(s, token)) /* get xyzw writemask */ - PARSE_ERROR; + RETURN_ERROR; dstReg->WriteMask[0] = GL_FALSE; dstReg->WriteMask[1] = GL_FALSE; @@ -926,12 +963,12 @@ Parse_MaskedDstReg(const char **s, struct fp_dst_register *dstReg) k++; } if (k == 0) { - PARSE_ERROR1("Bad writemask character"); + RETURN_ERROR1("Bad writemask character"); } /* peek optional cc mask */ if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; } else { dstReg->WriteMask[0] = GL_TRUE; @@ -947,10 +984,10 @@ Parse_MaskedDstReg(const char **s, struct fp_dst_register *dstReg) Parse_String(s, "("); if (!Parse_CondCodeMask(s, dstReg)) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ")")) /* consume ")" */ - PARSE_ERROR; + RETURN_ERROR1("Expected )"); return GL_TRUE; } @@ -978,12 +1015,12 @@ Parse_SwizzleSrcReg(const char **s, struct fp_src_register *srcReg) /* check for '-' */ if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] == '-') { (void) Parse_String(s, "-"); srcReg->NegateBase = GL_TRUE; if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; } else { srcReg->NegateBase = GL_FALSE; @@ -992,19 +1029,19 @@ Parse_SwizzleSrcReg(const char **s, struct fp_src_register *srcReg) /* Src reg can be R, H or a named fragment attrib */ if (token[0] == 'R' || token[0] == 'H') { if (!Parse_TempReg(s, &srcReg->Register)) - PARSE_ERROR; + RETURN_ERROR; } else if (token[0] == 'f') { if (!Parse_AttribReg(s, &srcReg->Register)) - PARSE_ERROR; + RETURN_ERROR; } else if (token[0] == 'p') { if (!Parse_ProgramParamReg(s, &srcReg->Register)) - PARSE_ERROR; + RETURN_ERROR; } else { /* Also parse defined/declared constant or vector literal */ - PARSE_ERROR2("Bad source register name", token); + RETURN_ERROR2("Bad source register name", token); } /* init swizzle fields */ @@ -1015,15 +1052,15 @@ Parse_SwizzleSrcReg(const char **s, struct fp_src_register *srcReg) /* Look for optional swizzle suffix */ if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] == '.') { (void) Parse_String(s, "."); /* consume . */ if (!Parse_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_SwizzleSuffix(token, srcReg->Swizzle)) - PARSE_ERROR1("Bad swizzle suffix"); + RETURN_ERROR1("Bad swizzle suffix"); } return GL_TRUE; @@ -1037,12 +1074,12 @@ Parse_ScalarSrcReg(const char **s, struct fp_src_register *srcReg) /* check for '-' */ if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] == '-') { srcReg->NegateBase = GL_TRUE; (void) Parse_String(s, "-"); /* consume '-' */ if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; } else { srcReg->NegateBase = GL_FALSE; @@ -1051,22 +1088,22 @@ Parse_ScalarSrcReg(const char **s, struct fp_src_register *srcReg) /* Src reg can be R, H or a named fragment attrib */ if (token[0] == 'R' || token[0] == 'H') { if (!Parse_TempReg(s, &srcReg->Register)) - PARSE_ERROR; + RETURN_ERROR; } else if (token[0] == 'f') { if (!Parse_AttribReg(s, &srcReg->Register)) - PARSE_ERROR; + RETURN_ERROR; } else { - PARSE_ERROR2("Bad source register name", token); + RETURN_ERROR2("Bad source register name", token); } /* Look for .[xyzw] suffix */ if (!Parse_String(s, ".")) - PARSE_ERROR; + RETURN_ERROR1("Expected ."); if (!Parse_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] == 'x' && token[1] == 0) { srcReg->Swizzle[0] = 0; @@ -1081,7 +1118,7 @@ Parse_ScalarSrcReg(const char **s, struct fp_src_register *srcReg) srcReg->Swizzle[0] = 3; } else { - PARSE_ERROR1("Bad scalar source suffix"); + RETURN_ERROR1("Bad scalar source suffix"); } srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0; @@ -1111,6 +1148,7 @@ Parse_InstructionSequence(struct fragment_program *fragProg, if (!Parse_Token(s, token)) { inst->Opcode = FP_OPCODE_END; printf("END OF PROGRAM %d\n", count); + count++; break; } @@ -1119,13 +1157,13 @@ Parse_InstructionSequence(struct fragment_program *fragProg, char id[100]; GLfloat value[7]; /* yes, 7 to be safe */ if (!Parse_Identifier(s, id)) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, "=")) - PARSE_ERROR1("Expected = symbol"); + RETURN_ERROR1("Expected ="); if (!Parse_VectorOrScalarConstant(s, value)) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ";")) - PARSE_ERROR1("Expected ;"); + RETURN_ERROR1("Expected ;"); printf("Parsed DEFINE %s = %f %f %f %f\n", id, value[0], value[1], value[2], value[3]); _mesa_add_symbol(&(fragProg->SymbolTable), id, Definition, value); @@ -1134,13 +1172,13 @@ Parse_InstructionSequence(struct fragment_program *fragProg, char id[100]; GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0}; /* yes, to be safe */ if (!Parse_Identifier(s, id)) - PARSE_ERROR; + RETURN_ERROR; if (!Peek_Token(s, token)) - PARSE_ERROR; + RETURN_ERROR; if (token[0] == '=') { Parse_String(s, "="); if (!Parse_VectorOrScalarConstant(s, value)) - PARSE_ERROR; + RETURN_ERROR; printf("Parsed DECLARE %s = %f %f %f %f\n", id, value[0], value[1], value[2], value[3]); } @@ -1148,7 +1186,7 @@ Parse_InstructionSequence(struct fragment_program *fragProg, printf("Parsed DECLARE %s\n", id); } if (!Parse_String(s, ";")) - PARSE_ERROR1("Expected ;"); + RETURN_ERROR1("Expected ;"); _mesa_add_symbol(&(fragProg->SymbolTable), id, Declaration, value); } else { @@ -1159,7 +1197,7 @@ Parse_InstructionSequence(struct fragment_program *fragProg, if (instMatch.opcode < 0) { /* bad instruction name */ printf("-------- errror\n"); - PARSE_ERROR2("Unexpected token: ", token); + RETURN_ERROR2("Unexpected token: ", token); } inst->Opcode = instMatch.opcode; @@ -1172,91 +1210,93 @@ Parse_InstructionSequence(struct fragment_program *fragProg, */ if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) { if (!Parse_MaskedDstReg(s, &inst->DstReg)) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); } else if (instMatch.outputs == OUTPUT_NONE) { ASSERT(instMatch.opcode == FP_OPCODE_KIL); /* This is a little weird, the cond code info is in the dest register */ if (!Parse_CondCodeMask(s, &inst->DstReg)) - PARSE_ERROR; + RETURN_ERROR; } if (instMatch.inputs == INPUT_1V) { if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; + RETURN_ERROR; } else if (instMatch.inputs == INPUT_2V) { if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; + RETURN_ERROR; } else if (instMatch.inputs == INPUT_3V) { if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; + RETURN_ERROR; } else if (instMatch.inputs == INPUT_1S) { if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; + RETURN_ERROR; } else if (instMatch.inputs == INPUT_2S) { if (!Parse_ScalarSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; + RETURN_ERROR; } else if (instMatch.inputs == INPUT_CC) { + /* #if 00 if (!ParseCondCodeSrc(s, &inst->srcReg[0])) - PARSE_ERROR; + RETURN_ERROR; #endif + */ } else if (instMatch.inputs == INPUT_1V_T) { if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) - PARSE_ERROR; + RETURN_ERROR; } - else if (instMatch.inputs == INPUT_1V_T) { + else if (instMatch.inputs == INPUT_3V_T) { if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[2])) - PARSE_ERROR; + RETURN_ERROR; if (!Parse_String(s, ",")) - PARSE_ERROR; + RETURN_ERROR1("Expected ,"); if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) - PARSE_ERROR; + RETURN_ERROR; } /* end of statement semicolon */ if (!Parse_String(s, ";")) - PARSE_ERROR; + RETURN_ERROR1("Expected ;"); count++; if (count >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) - PARSE_ERROR1("Program too long"); + RETURN_ERROR1("Program too long"); } } return GL_TRUE; @@ -1473,7 +1513,7 @@ PrintSrcReg(const struct fp_src_register *src) _mesa_printf("%cC", "HR"[r]); } else { - _mesa_problem(NULL, "Bad fragment register"); + _mesa_problem(NULL, "Bad fragment register %d", src->Register); return; } if (src->Swizzle[0] == src->Swizzle[1] && @@ -1496,6 +1536,31 @@ PrintSrcReg(const struct fp_src_register *src) } } +static void +PrintTextureSrc(const struct fp_instruction *inst) +{ + _mesa_printf("TEX%d, ", inst->TexSrcUnit); + switch (inst->TexSrcTarget) { + case GL_TEXTURE_1D: + _mesa_printf("1D"); + break; + case GL_TEXTURE_2D: + _mesa_printf("2D"); + break; + case GL_TEXTURE_3D: + _mesa_printf("3D"); + break; + case GL_TEXTURE_RECTANGLE_NV: + _mesa_printf("RECT"); + break; + case GL_TEXTURE_CUBE_MAP: + _mesa_printf("CUBE"); + break; + default: + _mesa_problem(NULL, "Bad textue target in PrintTextureSrc"); + } +} + static void PrintCondCode(const struct fp_dst_register *dst) { @@ -1537,7 +1602,7 @@ PrintDstReg(const struct fp_dst_register *dst) _mesa_printf("H[%s]", InputRegisters[r]); } else if ((r = TempRegisterNumber(dst->Register)) >= 0) { - _mesa_printf("R[%s]", InputRegisters[r]); + _mesa_printf("R%d", r); } else if ((r = ProgramRegisterNumber(dst->Register)) >= 0) { _mesa_printf("p[%d]", r); @@ -1625,7 +1690,20 @@ _mesa_print_nv_fragment_program(const struct fragment_program *program) _mesa_printf(", "); PrintSrcReg(&inst->SrcReg[2]); } - + else if (Instructions[i].inputs == INPUT_1V_T) { + PrintSrcReg(&inst->SrcReg[0]); + _mesa_printf(", "); + PrintTextureSrc(inst); + } + else if (Instructions[i].inputs == INPUT_3V_T) { + PrintSrcReg(&inst->SrcReg[0]); + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[1]); + _mesa_printf(", "); + PrintSrcReg(&inst->SrcReg[2]); + _mesa_printf(", "); + PrintTextureSrc(inst); + } _mesa_printf(";\n"); break; } @@ -1635,4 +1713,3 @@ _mesa_print_nv_fragment_program(const struct fragment_program *program) } } } - diff --git a/src/mesa/main/nvfragprog.h b/src/mesa/main/nvfragprog.h index 687ebb2a1cb..10964632544 100644 --- a/src/mesa/main/nvfragprog.h +++ b/src/mesa/main/nvfragprog.h @@ -1,4 +1,4 @@ -/* $Id: nvfragprog.h,v 1.1 2003/01/14 04:55:46 brianp Exp $ */ +/* $Id: nvfragprog.h,v 1.2 2003/02/17 15:38:03 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -100,7 +100,7 @@ enum fp_opcode { FP_OPCODE_STR, FP_OPCODE_SUB, FP_OPCODE_TEX, - FP_OPCODE_TXC, + FP_OPCODE_TXD, FP_OPCODE_TXP, FP_OPCODE_UP2H, FP_OPCODE_UP2US, diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index 0980b5dab0b..6ff4569a8e8 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -1,4 +1,4 @@ -/* $Id: s_nvfragprog.c,v 1.1 2003/01/14 04:57:47 brianp Exp $ */ +/* $Id: s_nvfragprog.c,v 1.2 2003/02/17 15:38:04 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -36,6 +36,73 @@ #include "s_nvfragprog.h" +/** + * Fetch a texel. + */ +static void +fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit, + GLenum target, GLfloat color[4] ) +{ + const struct gl_texture_object *texObj; + + /* XXX Use swrast->TextureSample[texUnit]() to sample texture. + * Needs to be swrast->TextureSample[target][texUnit]() though. + */ + + switch (target) { + case GL_TEXTURE_1D: + texObj = ctx->Texture.Unit[unit].Current1D; + break; + case GL_TEXTURE_2D: + texObj = ctx->Texture.Unit[unit].Current2D; + break; + case GL_TEXTURE_3D: + texObj = ctx->Texture.Unit[unit].Current3D; + break; + case GL_TEXTURE_CUBE_MAP: + texObj = ctx->Texture.Unit[unit].CurrentCubeMap; + break; + case GL_TEXTURE_RECTANGLE_NV: + texObj = ctx->Texture.Unit[unit].CurrentRect; + break; + default: + _mesa_problem(ctx, "Invalid target in fetch_texel"); + } + + if (texObj->Complete) { + const struct gl_texture_image *texImage; + GLint col, row, img; + GLchan texel[4]; + col = IROUND(texcoord[0] * texImage->Width); /* XXX temporary! */ + row = IROUND(texcoord[1] * texImage->Height); /* XXX temporary! */ + img = 0; + texImage->FetchTexel(texImage, col, row, img, texel); + /* XXX texture format? */ + color[0] = CHAN_TO_FLOAT(texel[0]); + color[1] = CHAN_TO_FLOAT(texel[1]); + color[2] = CHAN_TO_FLOAT(texel[2]); + color[3] = CHAN_TO_FLOAT(texel[3]); + } + else { + ASSIGN_4V(color, 0.0, 0.0, 0.0, 0.0); + } +} + + +/** + * Fetch a texel w/ partial derivatives. + */ +static void +fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], + const GLfloat dtdx[4], const GLfloat dtdy[4], + GLuint unit, GLenum target, GLfloat color[4] ) +{ + /* XXX to do */ + +} + + + /** * Fetch a 4-element float vector from the given source register. * Apply swizzling and negating as needed. @@ -315,6 +382,44 @@ execute_program(GLcontext *ctx, const struct fragment_program *program) inst->UpdateCondRegister ); } break; + case FP_OPCODE_TEX: + /* Texel lookup */ + { + GLfloat texcoord[4], color[4]; + fetch_vector4( &inst->SrcReg[0], machine, texcoord ); + fetch_texel( ctx, texcoord, inst->TexSrcUnit, + inst->TexSrcTarget, color ); + store_vector4( &inst->DstReg, machine, color, inst->Saturate, + inst->UpdateCondRegister ); + } + break; + case FP_OPCODE_TXD: + /* Texture lookup w/ partial derivatives for LOD */ + { + GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; + fetch_vector4( &inst->SrcReg[0], machine, texcoord ); + fetch_vector4( &inst->SrcReg[1], machine, dtdx ); + fetch_vector4( &inst->SrcReg[2], machine, dtdy ); + fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit, + inst->TexSrcTarget, color ); + store_vector4( &inst->DstReg, machine, color, inst->Saturate, + inst->UpdateCondRegister ); + } + break; + case FP_OPCODE_TXP: + /* Texture lookup w/ perspective divide */ + { + GLfloat texcoord[4], color[4]; + fetch_vector4( &inst->SrcReg[0], machine, texcoord ); + texcoord[0] /= texcoord[3]; + texcoord[1] /= texcoord[3]; + texcoord[2] /= texcoord[3]; + fetch_texel( ctx, texcoord, inst->TexSrcUnit, + inst->TexSrcTarget, color ); + store_vector4( &inst->DstReg, machine, color, inst->Saturate, + inst->UpdateCondRegister ); + } + break; default: _mesa_problem(ctx, "Bad opcode in _mesa_exec_fragment_program"); return;