aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2003-03-14 15:40:59 +0000
committerBrian Paul <[email protected]>2003-03-14 15:40:59 +0000
commitf386f73f9e4054a750d453fa2f5449c2f1d2e242 (patch)
tree5ced5cfb6cb7f5006cc67618dac6eb83bdf93e4d
parenta2da1155c285fde2a5e5824d50ee8a57c6e982f5 (diff)
Clean-up of parser error handling/reporting.
Basic fragment program texture instructions are limping along.
-rw-r--r--src/mesa/main/nvfragparse.c210
-rw-r--r--src/mesa/main/nvfragprog.h16
-rw-r--r--src/mesa/main/nvprogram.c58
-rw-r--r--src/mesa/main/nvvertparse.c108
-rw-r--r--src/mesa/swrast/s_context.c38
-rw-r--r--src/mesa/swrast/s_nvfragprog.c36
-rw-r--r--src/mesa/swrast/s_triangle.c3
7 files changed, 285 insertions, 184 deletions
diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c
index f7eda38cc42..60b15bcd06e 100644
--- a/src/mesa/main/nvfragparse.c
+++ b/src/mesa/main/nvfragparse.c
@@ -1,4 +1,4 @@
-/* $Id: nvfragparse.c,v 1.12 2003/03/01 01:50:22 brianp Exp $ */
+/* $Id: nvfragparse.c,v 1.13 2003/03/14 15:40:59 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -70,15 +70,11 @@
#define OUTPUT_NONE 22
/* Optional suffixes */
-#define _R 0x01 /* real */
-#define _H 0x02 /* half */
-#define _X 0x04 /* fixed */
-#define _C 0x08 /* set cond codes */
-#define _S 0x10 /* saturate */
-
-#define SINGLE _R
-#define HALF _H
-#define FIXED _X
+#define _R FLOAT32 /* float */
+#define _H FLOAT16 /* half-float */
+#define _X FIXED12 /* fixed */
+#define _C 0x08 /* set cond codes */
+#define _S 0x10 /* saturate, clamp result to [0,1] */
struct instruction_pattern {
const char *name;
@@ -138,16 +134,73 @@ static const struct instruction_pattern Instructions[] = {
};
-
+/*
+ * Information needed or computed during parsing.
+ * Remember, we can't modify the target program object until we've
+ * _successfully_ parsed the program text.
+ */
struct parse_state {
+ GLcontext *ctx;
+ const GLubyte *start; /* start of program string */
const GLubyte *pos; /* current position */
struct fragment_program *program; /* current program */
GLuint numInst; /* number of instructions parsed */
GLuint inputsRead; /* bitmask of input registers used */
GLuint outputsWritten; /* 2 = depth register */
+ GLuint texturesUsed[MAX_TEXTURE_IMAGE_UNITS];
};
+/*
+ * Called whenever we find an error during parsing.
+ */
+static void
+record_error(struct parse_state *parseState, const char *msg, int lineNo)
+{
+#ifdef DEBUG
+ GLint line, column;
+ const GLubyte *lineStr;
+ lineStr = _mesa_find_line_column(parseState->start,
+ parseState->pos, &line, &column);
+ _mesa_debug(parseState->ctx,
+ "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
+ lineNo, line, column, (char *) lineStr, msg);
+ _mesa_free((void *) lineStr);
+#else
+ (void) lineNo;
+#endif
+
+ /* Check that no error was already recorded. Only record the first one. */
+ if (parseState->ctx->Program.ErrorString[0] == 0) {
+ _mesa_set_program_error(parseState->ctx,
+ parseState->pos - parseState->start,
+ msg);
+ }
+}
+
+
+#define RETURN_ERROR \
+do { \
+ record_error(parseState, "Unexpected end of input.", __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+#define RETURN_ERROR1(msg) \
+do { \
+ record_error(parseState, msg, __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+#define RETURN_ERROR2(msg1, msg2) \
+do { \
+ char err[1000]; \
+ _mesa_sprintf(err, "%s %s", msg1, msg2); \
+ record_error(parseState, err, __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+
+
/*
* Search a list of instruction structures for a match.
@@ -331,35 +384,6 @@ static const char *OutputRegisters[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS + 1] = {
};
-#ifdef DEBUG
-
-#define RETURN_ERROR \
-do { \
- _mesa_printf("nvfragparse.c error at %d: parse error\n", __LINE__); \
- return GL_FALSE; \
-} while(0)
-
-#define RETURN_ERROR1(msg) \
-do { \
- _mesa_printf("nvfragparse.c error at %d: %s\n", __LINE__, msg); \
- return GL_FALSE; \
-} while(0)
-
-#define RETURN_ERROR2(msg1, msg2) \
-do { \
- _mesa_printf("nvfragparse.c error at %d: %s %s\n", __LINE__, msg1, msg2);\
- return GL_FALSE; \
-} while(0)
-
-#else
-
-#define RETURN_ERROR return GL_FALSE
-#define RETURN_ERROR1(msg1) return GL_FALSE
-#define RETURN_ERROR2(msg1, msg2) return GL_FALSE
-
-#endif
-
-
static GLint
TempRegisterNumber(GLuint r)
{
@@ -576,7 +600,7 @@ Parse_VectorOrScalarConstant(struct parse_state *parseState, GLfloat *vec)
*/
static GLboolean
Parse_TextureImageId(struct parse_state *parseState,
- GLuint *texUnit, GLuint *texTargetIndex)
+ GLubyte *texUnit, GLubyte *texTargetBit)
{
GLubyte imageSrc[100];
GLint unit;
@@ -600,27 +624,27 @@ Parse_TextureImageId(struct parse_state *parseState,
RETURN_ERROR1("Expected ,");
if (Parse_String(parseState, "1D")) {
- *texTargetIndex = TEXTURE_1D_INDEX;
+ *texTargetBit = TEXTURE_1D_BIT;
}
else if (Parse_String(parseState, "2D")) {
- *texTargetIndex = TEXTURE_2D_INDEX;
+ *texTargetBit = TEXTURE_2D_BIT;
}
else if (Parse_String(parseState, "3D")) {
- *texTargetIndex = TEXTURE_3D_INDEX;
+ *texTargetBit = TEXTURE_3D_BIT;
}
else if (Parse_String(parseState, "CUBE")) {
- *texTargetIndex = TEXTURE_CUBE_INDEX;
+ *texTargetBit = TEXTURE_CUBE_BIT;
}
else if (Parse_String(parseState, "RECT")) {
- *texTargetIndex = TEXTURE_RECT_INDEX;
+ *texTargetBit = TEXTURE_RECT_BIT;
}
else {
RETURN_ERROR1("Invalid texture target token");
}
/* update record of referenced texture units */
- parseState->program->TexturesUsed[*texUnit] |= (1 << *texTargetIndex);
- if (_mesa_bitcount(parseState->program->TexturesUsed[*texUnit]) > 1) {
+ parseState->texturesUsed[*texUnit] |= *texTargetBit;
+ if (_mesa_bitcount(parseState->texturesUsed[*texUnit]) > 1) {
RETURN_ERROR1("Only one texture target can be used per texture unit.");
}
@@ -700,7 +724,7 @@ Parse_CondCodeMask(struct parse_state *parseState,
RETURN_ERROR;
if (!Parse_SwizzleSuffix(token, dstReg->CondSwizzle))
- RETURN_ERROR1("Bad swizzle suffix");
+ RETURN_ERROR1("Invalid swizzle suffix");
}
return GL_TRUE;
@@ -726,11 +750,11 @@ Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
if (token[0] == 'H')
reg += 32;
if (reg >= MAX_NV_FRAGMENT_PROGRAM_TEMPS)
- RETURN_ERROR1("Bad temporary register name");
+ RETURN_ERROR1("Invalid temporary register name");
*tempRegNum = FP_TEMP_REG_START + reg;
}
else {
- RETURN_ERROR1("Bad temporary register name");
+ RETURN_ERROR1("Invalid temporary register name");
}
return GL_TRUE;
@@ -750,7 +774,7 @@ Parse_DummyReg(struct parse_state *parseState, GLint *regNum)
*regNum = FP_DUMMY_REG_START + 1;
}
else {
- RETURN_ERROR1("Bad write-only register name");
+ RETURN_ERROR1("Invalid write-only register name");
}
return GL_TRUE;
@@ -775,7 +799,7 @@ Parse_ProgramParamReg(struct parse_state *parseState, GLint *regNum)
/* a numbered program parameter register */
GLint reg = _mesa_atoi((const char *) token);
if (reg >= MAX_NV_FRAGMENT_PROGRAM_PARAMS)
- RETURN_ERROR1("Bad constant program number");
+ RETURN_ERROR1("Invalid constant program number");
*regNum = FP_PROG_REG_START + reg;
}
else {
@@ -815,7 +839,7 @@ Parse_FragReg(struct parse_state *parseState, GLint *tempRegNum)
}
if (!InputRegisters[j]) {
/* unknown input register label */
- RETURN_ERROR2("Bad register name", token);
+ RETURN_ERROR2("Invalid register name", token);
}
/* Match '[' */
@@ -852,7 +876,7 @@ Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
}
}
if (!OutputRegisters[j])
- RETURN_ERROR1("Unrecognized output register name");
+ RETURN_ERROR1("Invalid output register name");
/* Match ']' */
if (!Parse_String(parseState, "]"))
@@ -889,7 +913,7 @@ Parse_MaskedDstReg(struct parse_state *parseState,
RETURN_ERROR;
}
else {
- RETURN_ERROR1("Bad destination register name");
+ RETURN_ERROR1("Invalid destination register name");
}
/* Parse optional write mask */
@@ -922,7 +946,7 @@ Parse_MaskedDstReg(struct parse_state *parseState,
k++;
}
if (k == 0) {
- RETURN_ERROR1("Bad writemask character");
+ RETURN_ERROR1("Invalid writemask character");
}
}
@@ -1039,7 +1063,7 @@ Parse_VectorSrc(struct parse_state *parseState,
srcReg->Register = 0; /* XXX fix */
}
else {
- RETURN_ERROR2("Bad source register name", token);
+ RETURN_ERROR2("Invalid source register name", token);
}
/* init swizzle fields */
@@ -1054,7 +1078,7 @@ Parse_VectorSrc(struct parse_state *parseState,
RETURN_ERROR;
if (!Parse_SwizzleSuffix(token, srcReg->Swizzle))
- RETURN_ERROR1("Bad swizzle suffix");
+ RETURN_ERROR1("Invalid swizzle suffix");
}
/* Finish absolute value */
@@ -1093,7 +1117,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
RETURN_ERROR;
}
else {
- RETURN_ERROR2("Bad source register name", token);
+ RETURN_ERROR2("Invalid source register name", token);
}
/* Look for .[xyzw] suffix */
@@ -1116,7 +1140,7 @@ Parse_ScalarSrcReg(struct parse_state *parseState,
srcReg->Swizzle[0] = 3;
}
else {
- RETURN_ERROR1("Bad scalar source suffix");
+ RETURN_ERROR1("Invalid scalar source suffix");
}
srcReg->Swizzle[1] = srcReg->Swizzle[2] = srcReg->Swizzle[3] = 0;
@@ -1178,21 +1202,26 @@ Parse_InstructionSequence(struct parse_state *parseState,
_mesa_add_symbol(&(parseState->program->SymbolTable),
(const char *) id, Declaration, value);
}
+ else if (Parse_String(parseState, "END")) {
+ inst->Opcode = FP_OPCODE_END;
+ 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)) {
- inst->Opcode = FP_OPCODE_END;
- parseState->numInst++;
- break;
+ RETURN_ERROR1("Missing END instruction.");
}
/* try to find matching instuction */
instMatch = MatchInstruction(token);
if (instMatch.opcode < 0) {
/* bad instruction name */
- printf("-------- errror\n");
RETURN_ERROR2("Unexpected token: ", token);
}
@@ -1262,7 +1291,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
if (!Parse_String(parseState, ","))
RETURN_ERROR1("Expected ,");
if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit,
- &inst->TexSrcIndex))
+ &inst->TexSrcBit))
RETURN_ERROR;
}
else if (instMatch.inputs == INPUT_3V_T) {
@@ -1279,7 +1308,7 @@ Parse_InstructionSequence(struct parse_state *parseState,
if (!Parse_String(parseState, ","))
RETURN_ERROR1("Expected ,");
if (!Parse_TextureImageId(parseState, &inst->TexSrcUnit,
- &inst->TexSrcIndex))
+ &inst->TexSrcBit))
RETURN_ERROR;
}
@@ -1324,9 +1353,15 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
programString[len] = 0;
/* Get ready to parse */
+ _mesa_bzero(&parseState, sizeof(struct parse_state));
+ parseState.ctx = ctx;
+ parseState.start = programString;
parseState.program = program;
parseState.numInst = 0;
+ /* Reset error state */
+ _mesa_set_program_error(ctx, -1, NULL);
+
/* check the program header */
if (_mesa_strncmp((const char *) programString, "!!FP1.0", 7) == 0) {
target = GL_FRAGMENT_PROGRAM_NV;
@@ -1354,7 +1389,8 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
}
if (Parse_InstructionSequence(&parseState, instBuffer)) {
- /* success! */
+ GLuint u;
+ /* successful parse! */
if (parseState.outputsWritten == 0) {
/* must write at least one output! */
@@ -1386,6 +1422,8 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
program->Instructions = newInst;
program->InputsRead = parseState.inputsRead;
program->OutputsWritten = parseState.outputsWritten;
+ for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++)
+ program->TexturesUsed[u] = parseState.texturesUsed[u];
/* allocate registers for declared program parameters */
_mesa_assign_program_registers(&(program->SymbolTable));
@@ -1399,18 +1437,7 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget,
else {
/* Error! */
_mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
- ctx->Program.ErrorPos = (GLubyte *) parseState.pos - programString;
-#ifdef DEBUG
- {
- GLint line, column;
- const GLubyte *lineStr;
- lineStr = _mesa_find_line_column(programString,
- parseState.pos, &line, &column);
- _mesa_debug(ctx, "Parse error on line %d, column %d:%s\n",
- line, column, (char *) lineStr);
- _mesa_free((void *) lineStr);
- }
-#endif
+ /* NOTE: _mesa_set_program_error would have been called already */
}
}
@@ -1449,7 +1476,7 @@ PrintSrcReg(const struct fp_src_register *src)
_mesa_printf("%cC", "HR"[r]);
}
else {
- _mesa_problem(NULL, "Bad fragment register %d", src->Register);
+ _mesa_problem(NULL, "Invalid fragment register %d", src->Register);
return;
}
if (src->Swizzle[0] == src->Swizzle[1] &&
@@ -1476,24 +1503,24 @@ static void
PrintTextureSrc(const struct fp_instruction *inst)
{
_mesa_printf("TEX%d, ", inst->TexSrcUnit);
- switch (inst->TexSrcIndex) {
- case TEXTURE_1D_INDEX:
+ switch (inst->TexSrcBit) {
+ case TEXTURE_1D_BIT:
_mesa_printf("1D");
break;
- case TEXTURE_2D_INDEX:
+ case TEXTURE_2D_BIT:
_mesa_printf("2D");
break;
- case TEXTURE_3D_INDEX:
+ case TEXTURE_3D_BIT:
_mesa_printf("3D");
break;
- case TEXTURE_RECT_INDEX:
+ case TEXTURE_RECT_BIT:
_mesa_printf("RECT");
break;
- case TEXTURE_CUBE_INDEX:
+ case TEXTURE_CUBE_BIT:
_mesa_printf("CUBE");
break;
default:
- _mesa_problem(NULL, "Bad textue target in PrintTextureSrc");
+ _mesa_problem(NULL, "Invalid textue target in PrintTextureSrc");
}
}
@@ -1588,9 +1615,9 @@ _mesa_print_nv_fragment_program(const struct fragment_program *program)
if (inst->Opcode == Instructions[i].opcode) {
/* print instruction name */
_mesa_printf("%s", Instructions[i].name);
- if (inst->Precision == HALF)
+ if (inst->Precision == FLOAT16)
_mesa_printf("H");
- else if (inst->Precision == FIXED)
+ else if (inst->Precision == FIXED12)
_mesa_printf("X");
if (inst->UpdateCondRegister)
_mesa_printf("C");
@@ -1645,7 +1672,8 @@ _mesa_print_nv_fragment_program(const struct fragment_program *program)
}
}
if (!Instructions[i].name) {
- _mesa_printf("Bad opcode %d\n", inst->Opcode);
+ _mesa_printf("Invalid opcode %d\n", inst->Opcode);
}
}
+ _mesa_printf("END\n");
}
diff --git a/src/mesa/main/nvfragprog.h b/src/mesa/main/nvfragprog.h
index d7ef8d42485..d7e23627a42 100644
--- a/src/mesa/main/nvfragprog.h
+++ b/src/mesa/main/nvfragprog.h
@@ -1,4 +1,4 @@
-/* $Id: nvfragprog.h,v 1.3 2003/02/23 04:09:21 brianp Exp $ */
+/* $Id: nvfragprog.h,v 1.4 2003/03/14 15:40:59 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -49,7 +49,7 @@
#define FP_DUMMY_REG_END (FP_DUMMY_REG_START + MAX_NV_FRAGMENT_PROGRAM_WRITE_ONLYS - 1)
-
+/* condition codes */
#define COND_GT 1 /* greater than zero */
#define COND_EQ 2 /* equal to zero */
#define COND_LT 3 /* less than zero */
@@ -61,6 +61,12 @@
#define COND_FL 9 /* always false */
+/* instruction precision */
+#define FLOAT32 0x1
+#define FLOAT16 0x2
+#define FIXED12 0x4
+
+
enum fp_opcode {
FP_OPCODE_ADD = 1000,
FP_OPCODE_COS,
@@ -139,9 +145,9 @@ struct fp_instruction
struct fp_dst_register DstReg;
GLboolean Saturate;
GLboolean UpdateCondRegister;
- GLuint Precision; /* SINGLE, HALF or FIXED */
- GLuint TexSrcUnit; /* texture unit for TEX, TXD, TXP instructions */
- GLuint TexSrcIndex; /* texture target for TEX, TXD, TXP instructions */
+ GLubyte Precision; /* FLOAT32, FLOAT16 or FIXED12 */
+ GLubyte TexSrcUnit; /* texture unit for TEX, TXD, TXP instructions */
+ GLubyte TexSrcBit; /* TEXTURE_1D,2D,3D,CUBE,RECT_BIT source target */
};
diff --git a/src/mesa/main/nvprogram.c b/src/mesa/main/nvprogram.c
index 1e255ba0288..4e371620c57 100644
--- a/src/mesa/main/nvprogram.c
+++ b/src/mesa/main/nvprogram.c
@@ -1,4 +1,4 @@
-/* $Id: nvprogram.c,v 1.7 2003/03/10 00:26:24 brianp Exp $ */
+/* $Id: nvprogram.c,v 1.8 2003/03/14 15:40:59 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -260,35 +260,41 @@ _mesa_BindProgramNV(GLenum target, GLuint id)
/* NOTE: binding to a non-existant program is not an error.
* That's supposed to be caught in glBegin.
*/
- prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
-
- if (!prog && id > 0){
- /* allocate new program */
- if (target == GL_VERTEX_PROGRAM_NV) {
- struct vertex_program *vprog = CALLOC_STRUCT(vertex_program);
- if (!vprog) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV");
- return;
+ if (id == 0) {
+ /* OK, the null program object */
+ prog = NULL;
+ }
+ else {
+ prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, id);
+
+ if (!prog && id > 0){
+ /* allocate new program */
+ if (target == GL_VERTEX_PROGRAM_NV) {
+ struct vertex_program *vprog = CALLOC_STRUCT(vertex_program);
+ if (!vprog) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV");
+ return;
+ }
+ prog = &(vprog->Base);
}
- prog = &(vprog->Base);
- }
- else if (target == GL_FRAGMENT_PROGRAM_NV) {
- struct fragment_program *fprog = CALLOC_STRUCT(fragment_program);
- if (!fprog) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV");
+ else if (target == GL_FRAGMENT_PROGRAM_NV) {
+ struct fragment_program *fprog = CALLOC_STRUCT(fragment_program);
+ if (!fprog) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramNV");
+ return;
+ }
+ prog = &(fprog->Base);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV(target)");
return;
}
- prog = &(fprog->Base);
+ prog->Id = id;
+ prog->Target = target;
+ prog->Resident = GL_TRUE;
+ prog->RefCount = 1;
+ _mesa_HashInsert(ctx->Shared->Programs, id, prog);
}
- else {
- _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramNV(target)");
- return;
- }
- prog->Id = id;
- prog->Target = target;
- prog->Resident = GL_TRUE;
- prog->RefCount = 1;
- _mesa_HashInsert(ctx->Shared->Programs, id, prog);
}
/* bind now */
diff --git a/src/mesa/main/nvvertparse.c b/src/mesa/main/nvvertparse.c
index 83215cb621a..a84eb34071e 100644
--- a/src/mesa/main/nvvertparse.c
+++ b/src/mesa/main/nvvertparse.c
@@ -1,4 +1,4 @@
-/* $Id: nvvertparse.c,v 1.3 2003/02/25 19:27:54 brianp Exp $ */
+/* $Id: nvvertparse.c,v 1.4 2003/03/14 15:40:59 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -47,6 +47,8 @@
* program attributes.
*/
struct parse_state {
+ GLcontext *ctx;
+ const GLubyte *start;
const GLubyte *pos;
GLboolean isStateProgram;
GLboolean isPositionInvariant;
@@ -58,6 +60,58 @@ struct parse_state {
};
+/*
+ * Called whenever we find an error during parsing.
+ */
+static void
+record_error(struct parse_state *parseState, const char *msg, int lineNo)
+{
+#ifdef DEBUG
+ GLint line, column;
+ const GLubyte *lineStr;
+ lineStr = _mesa_find_line_column(parseState->start,
+ parseState->pos, &line, &column);
+ _mesa_debug(parseState->ctx,
+ "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
+ lineNo, line, column, (char *) lineStr, msg);
+ _mesa_free((void *) lineStr);
+#else
+ (void) lineNo;
+#endif
+
+ /* Check that no error was already recorded. Only record the first one. */
+ if (parseState->ctx->Program.ErrorString[0] == 0) {
+ _mesa_set_program_error(parseState->ctx,
+ parseState->pos - parseState->start,
+ msg);
+ }
+}
+
+
+#define RETURN_ERROR \
+do { \
+ record_error(parseState, "Unexpected end of input.", __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+#define RETURN_ERROR1(msg) \
+do { \
+ record_error(parseState, msg, __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+#define RETURN_ERROR2(msg1, msg2) \
+do { \
+ char err[1000]; \
+ _mesa_sprintf(err, "%s %s", msg1, msg2); \
+ record_error(parseState, err, __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+
+
+
+
static GLboolean IsLetter(GLubyte b)
{
return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');
@@ -227,34 +281,6 @@ static const char *Opcodes[] = {
};
-#ifdef DEBUG
-
-#define RETURN_ERROR \
-do { \
- _mesa_printf("vert prog error at %d\n", __LINE__); \
- return GL_FALSE; \
-} while(0)
-
-#define RETURN_ERROR1(msg) \
-do { \
- _mesa_printf("vert prog error at %d: %s\n", __LINE__, msg); \
- return GL_FALSE; \
-} while(0)
-
-#define RETURN_ERROR2(msg1, msg2) \
-do { \
- _mesa_printf("vert prog error at %d: %s %s\n", __LINE__, msg1, msg2);\
- return GL_FALSE; \
-} while(0)
-
-#else
-
-#define RETURN_ERROR return GL_FALSE
-#define RETURN_ERROR1(msg1) return GL_FALSE
-#define RETURN_ERROR2(msg1, msg2) return GL_FALSE
-
-#endif
-
static GLuint
IsProgRegister(GLuint r)
@@ -1174,7 +1200,9 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
MEMCPY(programString, str, len);
programString[len] = 0;
- /* get ready to parse */
+ /* Get ready to parse */
+ parseState.ctx = ctx;
+ parseState.start = programString;
parseState.isPositionInvariant = GL_FALSE;
parseState.isVersion1_1 = GL_FALSE;
parseState.numInst = 0;
@@ -1182,6 +1210,9 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
parseState.outputsWritten = 0;
parseState.progRegsWritten = 0;
+ /* Reset error state */
+ _mesa_set_program_error(ctx, -1, NULL);
+
/* check the program header */
if (_mesa_strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
target = GL_VERTEX_PROGRAM_NV;
@@ -1268,19 +1299,12 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
}
else {
/* Error! */
- ctx->Program.ErrorPos = parseState.pos - str;
_mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
-#ifdef DEBUG
- {
- GLint line, column;
- const GLubyte *lineStr;
- lineStr = _mesa_find_line_column(programString,
- parseState.pos, &line, &column);
- _mesa_debug(ctx, "Parse error on line %d, column %d:%s\n",
- line, column, (char *) lineStr);
- _mesa_free((void *) lineStr);
- }
-#endif
+ /* NOTE: _mesa_set_program_error would have been called already */
+ /* GL_NV_vertex_program isn't supposed to set the error string
+ * so we reset it here.
+ */
+ _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
}
}
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index 2c3ffbedd77..6ed0c42e4d6 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -1,4 +1,4 @@
-/* $Id: s_context.c,v 1.45 2003/02/23 04:10:54 brianp Exp $ */
+/* $Id: s_context.c,v 1.46 2003/03/14 15:41:00 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -25,12 +25,13 @@
*
* Authors:
* Keith Whitwell <[email protected]>
+ * Brian Paul
*/
-#include "glheader.h"
+#include "imports.h"
#include "context.h"
#include "mtypes.h"
-#include "imports.h"
+#include "texobj.h"
#include "swrast.h"
#include "s_blend.h"
@@ -305,11 +306,40 @@ _swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit,
}
}
+ if (ctx->FragmentProgram.Enabled) {
+ ASSERT(ctx->FragmentProgram.Current);
+ /* only one target can be referenced per unit per fragment program */
+ switch (ctx->FragmentProgram.Current->TexturesUsed[texUnit]) {
+ case TEXTURE_1D_BIT:
+ tObj = ctx->Texture.Unit[texUnit].Current1D;
+ break;
+ case TEXTURE_2D_BIT:
+ tObj = ctx->Texture.Unit[texUnit].Current2D;
+ break;
+ case TEXTURE_3D_BIT:
+ tObj = ctx->Texture.Unit[texUnit].Current3D;
+ break;
+ case TEXTURE_CUBE_BIT:
+ tObj = ctx->Texture.Unit[texUnit].CurrentCubeMap;
+ break;
+ case TEXTURE_RECT_BIT:
+ tObj = ctx->Texture.Unit[texUnit].CurrentRect;
+ break;
+ default:
+ _mesa_problem(ctx, "Bad texture in _swrast_validate_texture_sample");
+ return;
+ }
+ if (!tObj->Complete) {
+ _mesa_test_texobj_completeness(ctx,
+ (struct gl_texture_object *) tObj );
+ }
+ }
+
swrast->TextureSample[texUnit] =
_swrast_choose_texture_sample_func( ctx, tObj );
swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, texcoords,
- lambda, rgba );
+ lambda, rgba );
/* GL_SGI_texture_color_table */
if (ctx->Texture.Unit[texUnit].ColorTableEnabled) {
diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c
index 147b5248d4c..c55080c0aac 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.6 2003/03/04 16:34:03 brianp Exp $ */
+/* $Id: s_nvfragprog.c,v 1.7 2003/03/14 15:41:00 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -33,7 +33,7 @@
#include "macros.h"
#include "s_nvfragprog.h"
-
+#include "s_texture.h"
/**
@@ -41,27 +41,27 @@
*/
static void
fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit,
- GLuint targetIndex, GLfloat color[4] )
+ GLuint targetBit, GLfloat color[4] )
{
const GLfloat *lambda = NULL;
GLchan rgba[4];
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_texture_object *texObj = NULL;
- switch (targetIndex) {
- case TEXTURE_1D_INDEX:
+ switch (targetBit) {
+ case TEXTURE_1D_BIT:
texObj = ctx->Texture.Unit[unit].Current1D;
break;
- case TEXTURE_2D_INDEX:
+ case TEXTURE_2D_BIT:
texObj = ctx->Texture.Unit[unit].Current2D;
break;
- case TEXTURE_3D_INDEX:
+ case TEXTURE_3D_BIT:
texObj = ctx->Texture.Unit[unit].Current3D;
break;
- case TEXTURE_CUBE_INDEX:
+ case TEXTURE_CUBE_BIT:
texObj = ctx->Texture.Unit[unit].CurrentCubeMap;
break;
- case TEXTURE_RECT_INDEX:
+ case TEXTURE_RECT_BIT:
texObj = ctx->Texture.Unit[unit].CurrentRect;
break;
default:
@@ -69,8 +69,12 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit,
}
swrast->TextureSample[unit](ctx, unit, texObj, 1,
- (const GLfloat (*)[4]) &texcoord,
+ (const GLfloat (*)[4]) texcoord,
lambda, &rgba);
+ color[0] = CHAN_TO_FLOAT(rgba[0]);
+ color[1] = CHAN_TO_FLOAT(rgba[1]);
+ color[2] = CHAN_TO_FLOAT(rgba[2]);
+ color[3] = CHAN_TO_FLOAT(rgba[3]);
}
@@ -80,7 +84,7 @@ fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLuint unit,
static void
fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
const GLfloat dtdx[4], const GLfloat dtdy[4],
- GLuint unit, GLuint targetIndex, GLfloat color[4] )
+ GLuint unit, GLuint targetBit, GLfloat color[4] )
{
/* XXX to do */
@@ -259,7 +263,9 @@ store_vector4( const struct fp_instruction *inst,
/**
- * Execute the given vertex program
+ * Execute the given vertex program.
+ * NOTE: we do everything in single-precision floating point; we don't
+ * currently observe the single/half/fixed-precision qualifiers.
* \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
*/
static GLboolean
@@ -696,7 +702,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program)
GLfloat texcoord[4], color[4];
fetch_vector4( &inst->SrcReg[0], machine, texcoord );
fetch_texel( ctx, texcoord, inst->TexSrcUnit,
- inst->TexSrcIndex, color );
+ inst->TexSrcBit, color );
store_vector4( inst, machine, color );
}
break;
@@ -708,7 +714,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program)
fetch_vector4( &inst->SrcReg[1], machine, dtdx );
fetch_vector4( &inst->SrcReg[2], machine, dtdy );
fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit,
- inst->TexSrcIndex, color );
+ inst->TexSrcBit, color );
store_vector4( inst, machine, color );
}
break;
@@ -721,7 +727,7 @@ execute_program(GLcontext *ctx, const struct fragment_program *program)
texcoord[1] /= texcoord[3];
texcoord[2] /= texcoord[3];
fetch_texel( ctx, texcoord, inst->TexSrcUnit,
- inst->TexSrcIndex, color );
+ inst->TexSrcBit, color );
store_vector4( inst, machine, color );
}
break;
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 76a45b96b5e..538102f41ff 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -1,4 +1,4 @@
-/* $Id: s_triangle.c,v 1.67 2003/03/01 01:50:26 brianp Exp $ */
+/* $Id: s_triangle.c,v 1.68 2003/03/14 15:41:00 brianp Exp $ */
/*
* Mesa 3-D graphics library
@@ -1066,6 +1066,7 @@ _swrast_choose_triangle( GLcontext *ctx )
/* First see if we can use an optimized 2-D texture function */
if (ctx->Texture._EnabledUnits == 1
+ && !ctx->FragmentProgram.Enabled
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
&& texObj2D->WrapS==GL_REPEAT
&& texObj2D->WrapT==GL_REPEAT