-/* $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
/**********************************************************************/
+/* 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;
/*
/**
- * 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);
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;
}
}
}
-static GLboolean
+/**
+ * Parse <number>, <varname> 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];
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;
/* 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))
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
return;
}
- if (Parse_Program(&s, instBuffer)) {
+ /* XXX temporary */
+ CurrentProgram = program;
+
+ if (Parse_InstructionSequence(program, &s, instBuffer)) {
GLuint numInst;
GLuint strLen;
GLuint inputsRead = 0;
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
}
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);
-/* $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
#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).
}
-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);
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;
}
GLfloat *params)
{
struct program *prog;
- const GLfloat *p;
+ struct fragment_program *fragProg;
+ GLint reg;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
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];
}