From f386f73f9e4054a750d453fa2f5449c2f1d2e242 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 14 Mar 2003 15:40:59 +0000 Subject: [PATCH] Clean-up of parser error handling/reporting. Basic fragment program texture instructions are limping along. --- src/mesa/main/nvfragparse.c | 210 +++++++++++++++++++-------------- src/mesa/main/nvfragprog.h | 16 ++- src/mesa/main/nvprogram.c | 58 +++++---- src/mesa/main/nvvertparse.c | 108 ++++++++++------- src/mesa/swrast/s_context.c | 38 +++++- src/mesa/swrast/s_nvfragprog.c | 36 +++--- src/mesa/swrast/s_triangle.c | 3 +- 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 + * 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 -- 2.30.2