From 2c1912fe84d110d4c8cccc207827a154c09dd09a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sun, 16 Feb 2003 23:07:34 +0000 Subject: [PATCH] more work on DEFINE/DECLARATION statements, symbol tables --- src/mesa/main/mtypes.h | 8 +- src/mesa/main/nvfragparse.c | 253 +++++++++++++++++++----------------- src/mesa/main/nvprogram.c | 122 +++++++++++++---- src/mesa/main/nvprogram.h | 24 +++- 4 files changed, 264 insertions(+), 143 deletions(-) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 4c3fb3bbd42..716bbfcf85c 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1,4 +1,4 @@ -/* $Id: mtypes.h,v 1.102 2003/01/26 14:37:15 brianp Exp $ */ +/* $Id: mtypes.h,v 1.103 2003/02/16 23:07:34 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1177,6 +1177,11 @@ struct fp_machine struct vp_instruction; struct fp_instruction; +struct symbol_table +{ + struct symbol *Head; +}; + /* Base class for any kind of program object */ struct program @@ -1208,6 +1213,7 @@ struct fragment_program GLuint InputsRead; /* Bitmask of which input regs are read */ GLuint OutputsWritten; /* Bitmask of which output regs are written to */ GLfloat LocalParams[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; + struct symbol_table SymbolTable; }; diff --git a/src/mesa/main/nvfragparse.c b/src/mesa/main/nvfragparse.c index 05d0ac5452e..7b9208d5211 100644 --- a/src/mesa/main/nvfragparse.c +++ b/src/mesa/main/nvfragparse.c @@ -1,4 +1,4 @@ -/* $Id: nvfragparse.c,v 1.3 2003/02/08 15:56:34 brianp Exp $ */ +/* $Id: nvfragparse.c,v 1.4 2003/02/16 23:07:35 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -142,14 +142,18 @@ static const struct instruction_pattern Instructions[] = { /**********************************************************************/ +/* XXX not used yet */ struct parse_state { const GLubyte *start; /* start of program */ const GLubyte *end; /* one char past end of the program */ const GLubyte *s; /* current position */ GLboolean IsStateProgram; GLboolean IsVersion1_1; + struct fragment_program *currentProgram; }; +/* XXX temporary hack */ +static struct fragment_program *CurrentProgram = NULL; /* @@ -476,13 +480,13 @@ Parse_Identifier(const char **s, char *ident) /** - * Parse a floating point constant. + * Parse a floating point constant, or a defined symbol name. * [+/-]N[.N[eN]] */ static GLboolean Parse_ScalarConstant(const char **s, GLfloat *number) { - char *end; + char *end = NULL; *number = (GLfloat) _mesa_strtod(*s, &end); @@ -496,8 +500,9 @@ Parse_ScalarConstant(const char **s, GLfloat *number) char ident[100]; if (!Parse_Identifier(s, ident)) PARSE_ERROR1("Expected an identifier"); - /* XXX Look up the value in the symbol table */ - *number = -999; + if (!_mesa_lookup_symbol(&(CurrentProgram->SymbolTable), ident, number)) { + PARSE_ERROR1("Undefined symbol"); + } return GL_TRUE; } } @@ -571,7 +576,11 @@ Parse_VectorConstant(const char **s, GLfloat *vec) } -static GLboolean +/** + * Parse , or {a, b, c, d}. + * Return number of values in the vector or scalar, or zero if parse error. + */ +static GLuint Parse_VectorOrScalarConstant(const char **s, GLfloat *vec) { char token[100]; @@ -1082,7 +1091,8 @@ Parse_ScalarSrcReg(const char **s, struct fp_src_register *srcReg) static GLboolean -Parse_InstructionSequence(const char **s, struct fp_instruction program[]) +Parse_InstructionSequence(struct fragment_program *fragProg, + const char **s, struct fp_instruction program[]) { char token[100]; GLint count = 0; @@ -1107,19 +1117,22 @@ Parse_InstructionSequence(const char **s, struct fp_instruction program[]) /* special instructions */ if (StrEq(token, "DEFINE")) { char id[100]; - GLfloat value[4]; + GLfloat value[7]; /* yes, 7 to be safe */ if (!Parse_Identifier(s, id)) PARSE_ERROR; if (!Parse_String(s, "=")) PARSE_ERROR1("Expected = symbol"); if (!Parse_VectorOrScalarConstant(s, value)) PARSE_ERROR; + if (!Parse_String(s, ";")) + PARSE_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); } else if (StrEq(token, "DECLARE")) { char id[100]; - GLfloat value[4]; + GLfloat value[7] = {0, 0, 0, 0, 0, 0, 0}; /* yes, to be safe */ if (!Parse_Identifier(s, id)) PARSE_ERROR; if (!Peek_Token(s, token)) @@ -1128,128 +1141,128 @@ Parse_InstructionSequence(const char **s, struct fp_instruction program[]) Parse_String(s, "="); if (!Parse_VectorOrScalarConstant(s, value)) PARSE_ERROR; - printf("Parsed DECLARE %s = %f %f %f %f\n", id, value[0], value[1], - value[2], value[3]); + printf("Parsed DECLARE %s = %f %f %f %f\n", id, + value[0], value[1], value[2], value[3]); } else { printf("Parsed DECLARE %s\n", id); } + if (!Parse_String(s, ";")) + PARSE_ERROR1("Expected ;"); + _mesa_add_symbol(&(fragProg->SymbolTable), id, Declaration, value); } + else { + /* arithmetic instruction */ + + /* try to find matching instuction */ + instMatch = MatchInstruction(token); + if (instMatch.opcode < 0) { + /* bad instruction name */ + printf("-------- errror\n"); + PARSE_ERROR2("Unexpected token: ", token); + } - /* try to find matching instuction */ - instMatch = MatchInstruction(token); - if (instMatch.opcode < 0) { - /* bad instruction name */ - PARSE_ERROR2("Unexpected token: ", token); - } - - inst->Opcode = instMatch.opcode; - inst->Precision = instMatch.suffixes & (_R | _H | _X); - inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE; - inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; + inst->Opcode = instMatch.opcode; + inst->Precision = instMatch.suffixes & (_R | _H | _X); + inst->Saturate = (instMatch.suffixes & (_S)) ? GL_TRUE : GL_FALSE; + inst->UpdateCondRegister = (instMatch.suffixes & (_C)) ? GL_TRUE : GL_FALSE; - /* - * parse the input and output operands - */ - if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) { - if (!Parse_MaskedDstReg(s, &inst->DstReg)) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - } - 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; - } + /* + * parse the input and output operands + */ + if (instMatch.outputs == OUTPUT_S || instMatch.outputs == OUTPUT_V) { + if (!Parse_MaskedDstReg(s, &inst->DstReg)) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + } + 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; + } - if (instMatch.inputs == INPUT_1V) { - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; - } - else if (instMatch.inputs == INPUT_2V) { - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; - } - else if (instMatch.inputs == INPUT_3V) { - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; - } - else if (instMatch.inputs == INPUT_1S) { - if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; - } - else if (instMatch.inputs == INPUT_2S) { - if (!Parse_ScalarSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; - } - else if (instMatch.inputs == INPUT_CC) { + if (instMatch.inputs == INPUT_1V) { + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) + PARSE_ERROR; + } + else if (instMatch.inputs == INPUT_2V) { + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) + PARSE_ERROR; + } + else if (instMatch.inputs == INPUT_3V) { + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) + PARSE_ERROR; + } + else if (instMatch.inputs == INPUT_1S) { + if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) + PARSE_ERROR; + } + else if (instMatch.inputs == INPUT_2S) { + if (!Parse_ScalarSrcReg(s, &inst->SrcReg[0])) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + if (!Parse_ScalarSrcReg(s, &inst->SrcReg[1])) + PARSE_ERROR; + } + else if (instMatch.inputs == INPUT_CC) { #if 00 - if (!ParseCondCodeSrc(s, &inst->srcReg[0])) - PARSE_ERROR; + if (!ParseCondCodeSrc(s, &inst->srcReg[0])) + PARSE_ERROR; #endif - } - else if (instMatch.inputs == INPUT_1V_T) { - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) - PARSE_ERROR; - } - else if (instMatch.inputs == INPUT_1V_T) { - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[2])) - PARSE_ERROR; - if (!Parse_String(s, ",")) - PARSE_ERROR; - if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) - PARSE_ERROR; - } + } + else if (instMatch.inputs == INPUT_1V_T) { + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) + PARSE_ERROR; + } + else if (instMatch.inputs == INPUT_1V_T) { + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[0])) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[1])) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + if (!Parse_SwizzleSrcReg(s, &inst->SrcReg[2])) + PARSE_ERROR; + if (!Parse_String(s, ",")) + PARSE_ERROR; + if (!Parse_TextureImageId(s, &inst->TexSrcUnit, &inst->TexSrcTarget)) + PARSE_ERROR; + } - /* end of statement semicolon */ - if (!Parse_String(s, ";")) - PARSE_ERROR; + /* end of statement semicolon */ + if (!Parse_String(s, ";")) + PARSE_ERROR; - count++; - if (count >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) - PARSE_ERROR1("Program too long"); + count++; + if (count >= MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS) + PARSE_ERROR1("Program too long"); + } } return GL_TRUE; } -static GLboolean -Parse_Program(const char **s, struct fp_instruction instBuffer[]) -{ - return Parse_InstructionSequence(s, instBuffer); -} - - /** * Parse/compile the 'str' returning the compiled 'program'. * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos @@ -1297,7 +1310,10 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, return; } - if (Parse_Program(&s, instBuffer)) { + /* XXX temporary */ + CurrentProgram = program; + + if (Parse_InstructionSequence(program, &s, instBuffer)) { GLuint numInst; GLuint strLen; GLuint inputsRead = 0; @@ -1323,10 +1339,10 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, if ((r = InputRegisterNumber(srcReg0)) >= 0 && !instBuffer[numInst].SrcReg[0].RelAddr) inputsRead |= (1 << r); - if ((r = InputRegisterNumber(srcReg1) >= 0 + if ((r = InputRegisterNumber(srcReg1)) >= 0 && !instBuffer[numInst].SrcReg[1].RelAddr) inputsRead |= (1 << r); - if ((r = InputRegisterNumber(srcReg2) >= 0 + if ((r = InputRegisterNumber(srcReg2)) >= 0 && !instBuffer[numInst].SrcReg[2].RelAddr) inputsRead |= (1 << r); #endif @@ -1367,6 +1383,9 @@ _mesa_parse_nv_fragment_program(GLcontext *ctx, GLenum dstTarget, } program->Instructions = newInst; + /* allocate registers for declared program parameters */ + _mesa_assign_program_registers(&(program->SymbolTable)); + #ifdef DEBUG _mesa_printf("--- glLoadProgramNV result ---\n"); _mesa_print_nv_fragment_program(program); diff --git a/src/mesa/main/nvprogram.c b/src/mesa/main/nvprogram.c index d09e7afbeee..b6960c0df8a 100644 --- a/src/mesa/main/nvprogram.c +++ b/src/mesa/main/nvprogram.c @@ -1,4 +1,4 @@ -/* $Id: nvprogram.c,v 1.2 2003/02/10 20:31:11 alanh Exp $ */ +/* $Id: nvprogram.c,v 1.3 2003/02/16 23:07:36 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -45,6 +45,86 @@ #include "nvprogram.h" +/** + * Symbol table entry. + * Used for named program parameters. + */ +struct symbol +{ + const char *Name; + enum symbol_type Type; + GLfloat Value[4]; + GLuint Register; + struct symbol *Next; +}; + + + +void +_mesa_add_symbol(struct symbol_table *symbolTable, + const char *name, enum symbol_type type, const GLfloat *value) +{ + struct symbol *s = MALLOC_STRUCT(symbol); + if (s) { + s->Name = _mesa_strdup(name); + s->Type = type; + s->Value[0] = value[0]; + s->Value[1] = value[1]; + s->Value[2] = value[2]; + s->Value[3] = value[3]; + s->Next = symbolTable->Head; + symbolTable->Head = s; + } +} + + +GLboolean +_mesa_lookup_symbol(const struct symbol_table *symbolTable, + const char *name, GLfloat *value) +{ + const struct symbol *s; + for (s = symbolTable->Head; s; s = s->Next) { + if (_mesa_strcmp(s->Name, name) == 0) { + value[0] = s->Value[0]; + value[1] = s->Value[1]; + value[2] = s->Value[2]; + value[3] = s->Value[3]; + return GL_TRUE; + } + } + printf("lookup %s failed\n", name); + return GL_FALSE; +} + + +static GLint +_mesa_lookup_program_register(const struct symbol_table *symbolTable, + GLsizei len, const GLubyte *name) +{ + const struct symbol *s; + for (s = symbolTable->Head; s; s = s->Next) { + if (_mesa_strcmp(s->Name, (const char *) name) == 0 && + _mesa_strlen(s->Name) == len) { + return s->Register; + } + } + return -1; +} + + +void +_mesa_assign_program_registers(struct symbol_table *symbolTable) +{ + struct symbol *s; + GLuint reg = 0; + for (s = symbolTable->Head; s; s = s->Next) { + if (s->Type == Declaration) { + s->Register = reg++; + } + } +} + + /** * Set the vertex/fragment program error state (position and error string). @@ -984,20 +1064,13 @@ _mesa_TrackMatrixNV(GLenum target, GLuint address, } -static GLfloat * -lookup_program_parameter(struct fragment_program *fprog, - GLsizei len, const GLubyte *name) -{ - return NULL; -} - - void glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { struct program *prog; - GLfloat *p; + struct fragment_program *fragProg; + GLint reg; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -1012,16 +1085,17 @@ glProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, return; } - p = lookup_program_parameter((struct fragment_program *) prog, len, name); - if (!p) { + fragProg = (struct fragment_program *) prog; + reg = _mesa_lookup_program_register(&(fragProg->SymbolTable), len, name); + if (reg < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramNamedParameterNV"); return; } - p[0] = x; - p[1] = y; - p[2] = z; - p[3] = w; + fragProg->LocalParams[reg][0] = x; + fragProg->LocalParams[reg][1] = y; + fragProg->LocalParams[reg][2] = z; + fragProg->LocalParams[reg][3] = w; } @@ -1056,7 +1130,8 @@ glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name, GLfloat *params) { struct program *prog; - const GLfloat *p; + struct fragment_program *fragProg; + GLint reg; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -1071,16 +1146,17 @@ glGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name, return; } - p = lookup_program_parameter((struct fragment_program *) prog, len, name); - if (!p) { + fragProg = (struct fragment_program *) prog; + reg = _mesa_lookup_program_register(&(fragProg->SymbolTable), len, name); + if (reg < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramNamedParameterNV"); return; } - params[0] = p[0]; - params[1] = p[1]; - params[2] = p[2]; - params[3] = p[3]; + params[0] = fragProg->LocalParams[reg][0]; + params[1] = fragProg->LocalParams[reg][1]; + params[2] = fragProg->LocalParams[reg][2]; + params[3] = fragProg->LocalParams[reg][3]; } diff --git a/src/mesa/main/nvprogram.h b/src/mesa/main/nvprogram.h index 3ede7057220..5d31ebba3bf 100644 --- a/src/mesa/main/nvprogram.h +++ b/src/mesa/main/nvprogram.h @@ -1,10 +1,10 @@ -/* $Id: nvprogram.h,v 1.1 2003/01/14 04:55:46 brianp Exp $ */ +/* $Id: nvprogram.h,v 1.2 2003/02/16 23:07:36 brianp Exp $ */ /* * Mesa 3-D graphics library * Version: 5.1 * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -32,6 +32,26 @@ #define NVPROGRAM_H +enum symbol_type +{ + Definition, + Declaration +}; + + +extern void +_mesa_add_symbol(struct symbol_table *symbolTable, + const char *name, enum symbol_type type, + const GLfloat *value); + +extern GLboolean +_mesa_lookup_symbol(const struct symbol_table *symbolTable, + const char *name, GLfloat *value); + +extern void +_mesa_assign_program_registers(struct symbol_table *symbolTable); + + extern void _mesa_set_program_error(GLcontext *ctx, GLint pos, const char *string); -- 2.30.2