summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2003-02-17 15:38:03 +0000
committerBrian Paul <[email protected]>2003-02-17 15:38:03 +0000
commit04cbad84e8241ced16f146e36b6959e4c78cfac1 (patch)
tree84b06edf944a3105532ab558ba67b0a54d99603b /src/mesa
parent2c1912fe84d110d4c8cccc207827a154c09dd09a (diff)
Implement parsing of texture instructions and prototype execution.
Misc parser clean-ups.
Diffstat (limited to 'src/mesa')
-rw-r--r--src/mesa/main/nvfragparse.c343
-rw-r--r--src/mesa/main/nvfragprog.h4
-rw-r--r--src/mesa/swrast/s_nvfragprog.c107
3 files changed, 318 insertions, 136 deletions
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 <name> 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<n>, H<n>, 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<n>, H<n> 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<n>, H<n> 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] &&
@@ -1497,6 +1537,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)
{
static const char *comps = "xyzw";
@@ -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
@@ -37,6 +37,73 @@
/**
+ * 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;